Using CustomValidator control - asp.net

We know usually the CustomValidator control will check the user's input against some arithmetic validation.
I have a textbox in my web form. The text of it doesn't come from user's input, it comes from the database.
MembershipUser user = Membership.Providers["SqlMembershipProvider"].GetUser(userName);
TextUserName.Text = AntiXss.HtmlEncode(user.UserName);
My goal is to use some kind of validator to check whether it is appropriate. If not then change it in the textbox and validate it again.
How to do it?
Thanks.
UPDATE CODE:
protected void ValidateUser()
{
string UserNameCreated = TextUserName.Text;
Match match = Regex.Match(UserNameCreated, #"^[a-zA-Z0-9]{6,}$",
RegexOptions.IgnoreCase);
}
<td class="style4">
<asp:TextBox ID="TextUserName" runat="server"></asp:TextBox>
</td><td><asp:CustomValidator ID="CustomValidatorUser" runat="server" ControlToValidate="TextUserName"
ErrorMessage="Minimum of 6 (six) alphanumeric characters."
OnServerValidate="ValidateUser" Display="Dynamic"
ValidateEmptyText="True" ></asp:CustomValidator></td>

Your ServerValidate has the wrong signature.
void ServerValidation(object source, ServerValidateEventArgs args)
{
args.IsValid = Regex.Match(TextUserName.Text, #"^[a-zA-Z0-9]{6,}$", RegexOptions.IgnoreCase);
}

Related

asp:CustomValidator - user input is equal to a set parameter

I am not too familiar with custom validation. If you are willing to help, it is MUCH appreciated!
<asp:CustomValidator ID="valMatchUserInput" runat="server" ControlToValidate="tbUserInput" ErrorMessage="Please do something."> </asp:CustomValidator>
Basically, if the user input does not match (is not equal to) a specific parameter, I would like an error message to display, so nothing happens until the user fixes the error.
Thanks!
I will give you an example...
Let's say this is your validator:
<asp:CustomValidator ID="valMatchUserInput" runat="server" ControlToValidate="tbUserInput" ErrorMessage="Please do something." **ClientValidationFunction="Bla_ClientValidate" OnServerValidate="Bla_ServerValidate"**> </asp:CustomValidator>
You have to include a server-side validation and a client-side validation.
Code behind (server-side)
protected void Bla_ServerValidate(object source, ServerValidateEventArgs args)
{
//Compare your parameter here
}
Javascript (client-side)
function bla_ClientValidate(sender, e) {
// Compare your parameter here
}
It should work then

CustomValidator using CustomValidationScript

I have an ASP.NET TextBox with a CustomValidation control that invokes client side validation script.
<asp:TextBox ID="txtSubsContrRbtAmt" runat="server"
CssClass="textEntry NumericInput" Width="150px"
Text="" onKeyUp="SumValues();" MaxLength="16"></asp:TextBox>
<asp:CustomValidator ID="cvalSubsContrRbtAmt" runat="server" ClientValidationFunction="ValidatetxtSubsContrRbtAmt"
ControlToValidate="txtSubsContrRbtAmt" CssClass="errlable" ErrorMessage="Max Decimals = 7"
SetFocusOnError="True" ValidationGroup="CarbsAdd"></asp:CustomValidator>
Here's the Client script:
function ValidatetxtSubsContrRbtAmt(source, args) {
var txtSubsContrRbtAmt = document.getElementById("<%=txtSubsContrRbtAmt.ClientID%>");
var amount = txtSubsContrRbtAmt.value;
args.IsValid = ValidAmount(amount);
if (!args.IsValid)
txtSubsContrRbtAmt.focus();
}
function ValidAmount(amount) {
if (isNumber(amount)) {
return (RoundToXDecimalPlaces(amount, 7) == amount);
}
else {
return true;
}
In the ValidatetxtSubsContrRbtAmt function, the "source" parameter is the CustomValidator. That control has a property "ControlToValidate." If I can get to it, I can programmatically retrieve the value from that control and not have to have a separate function to validate each textbox.
jQuery is too much for me at this point, I'm looking for a plain old Javascript approach, please.
You don't have to get the text box. You can get the value from args.Value. The focus should be set automatically if you set SetFocusOnError="true".
function ValidatetxtSubsContrRbtAmt(source, args) {
var amount = args.Value;
args.IsValid = ValidAmount(amount);
}
You should be able to get to the control from the source object.
function ValidatetxtSubsContrRbtAmt(source, args) {
var controlToFocusOn = source.ControlToValidate;
you can switch that out with "document.getElementByID()" to get the ID or whatever attribute you need
var controlId = document.getElementById(source.ControlToValidate).id;
}
now you can focus or do what you need with the control. I had to access the the actual ControlToValidate earlier today from a CustomValidator.

server side validation in asp.net?

hi all as i know that asp.net provide server side validation control which has there own built-in logic, so i want to ask here can we extend built-in logic, i means suppose we use compare validator for comparing two file at this point it will validate according to there built-in logic, but i want to add some code for compare validator, is this possible.
According to my knowledge in asp.net every control treated as class which has data and code so according to inheritance or extend can we add some code in validation control ?
It looks like you need to use
CustomValidator
You can use a custom function to define when your control passes your validation. In this case could be something like this.
void ServerValidation (object source, ServerValidateEventArgs args)
{
args.IsValid = //Define your validation here
}
CustomValidator is one option. If you rather going to implement validator similar to existing one, you can simply derive from it and override all necessary methods. But the most important method you should look for is the EvaluateIsValid.
A CustomValidator is better in situations when your logic is more likely unique. In case you want to use the logic in multiple places, I would recommend to use inheritance. It allows you to encapsulate the logic in class library if you want, CustomValidator doesn't.
In your markup:
<asp:TextBox id="Text1" runat="server" />
<asp:CustomValidator id="CustomValidator1"
ControlToValidate="Text1"
Display="Static"
ErrorMessage="Not an even number!"
ForeColor="green"
Font-Names="verdana"
Font-Size="10pt"
OnServerValidate="ServerValidation"
runat="server"/>
<asp:Button id="Button1"
Text="Validate"
OnClick="ValidateBtn_OnClick"
runat="server"/>
In the server side code:
void ValidateBtn_OnClick(object sender, EventArgs e)
{
// Display whether the page passed validation.
if (Page.IsValid)
{
Message.Text = "Page is valid.";
}
else
{
Message.Text = "Page is not valid!";
}
}
void ServerValidation(object source, ServerValidateEventArgs args)
{
try
{
// Test whether the value entered into the text box is even.
int i = int.Parse(args.Value);
args.IsValid = ((i%2) == 0);
}
catch(Exception ex)
{
args.IsValid = false;
}
}
This example is a shortened version of the one found at the documentation page for CustomValidator:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.customvalidator.aspx
Yes you can. Like Carlos's answer link will tell you. You can put the code in the code behind.(.cs file)

What determines the order validators fire in?

I have a webform with two custom validators:
One to validate that a string is a date. I don’t care what format, so long as it’s parseable.
Another to ensure that one date is equal to or greater than another. I just couldn’t get the compare validator to play nice with any date format.
<asp:TextBox ID="txtResourceStartDate" runat="server"
CssClass="textBox mandatory dateField" />
<asp:CustomValidator ID="valResourceStartDateIsDate" runat="server"
ControlToValidate="txtResourceStartDate" Display="None"
ErrorMessage="Start date must be a valid date"
OnServerValidate="Date_ServerValidate" />
<asp:TextBox ID="txtResourceEndDate" runat="server"
CssClass="textBox mandatory dateField" />
<asp:CustomValidator ID="valResourceEndDateIsDate" runat="server"
ControlToValidate="txtResourceEndDate" Display="None"
ErrorMessage="End date must be a valid date"
OnServerValidate="Date_ServerValidate" />
<asp:CustomValidator Display="None" Text="" ID="valForStartEndDate" runat="server"
OnServerValidate="ValidateStartEndDate"
ErrorMessage="Last day must be greater than or equal to first day" />
protected void Date_ServerValidate(object source, ServerValidateEventArgs args)
{
DateTime outDate;
args.IsValid = DateTime.TryParse(args.Value, out outDate);
}
protected void ValidateStartEndDate(object sender, ServerValidateEventArgs e)
{
e.IsValid = DateTime.Parse(txtResourceEndDate.Text) >=
DateTime.Parse(txtResourceStartDate.Text);
}
The problem is that the ValidateStartEndDate validator is firing before the Date_ServerValidate validator, so if the date is not valid, a format exception is thrown on DateTime.Parse. Obviously this validator could check for a valid date before parsing, but I’d really prefer to have a discrete validator with an appropriate message.
So the question is this: what determines the sequence with which the validators fire? Unless I’m missing something, this is not declared at the tag level.
You can't count on a certain sequence the validators will fire and also you shouldnt. You have to make sure for yourself that the order is irrelevant.
So you could
check for the valid date
simultaneously with the
Equal-Greater-Check.
First Call your IsDate-Validator's Validate()-Function and then check if it IsValid
All validators are added to the Page.Validators collection and validation runs through this collection in order. If your logic really should rely on this order: change the order of the validators in the ASPX-Page
Some interesting infos about Page-Validation: http://msdn.microsoft.com/en-us/library/aa479045.aspx
Validation control execution order is determined by the order of the controls in the ValidatorCollection returned by Page.Validators. This order is, in turn, determined by the order of the validation controls in the markup, with some exceptions (e.g. validators within data-bound controls will get added to the collection later, and so will be at the end).
If you set CausesValidation=false on your button and then trigger validation manually with Page.Validate, you can use the Add and Remove methods on the ValidatorCollection to change the execution order:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack) {
// move myValidator to the very end, so it executes last
Validators.Remove(myValidator);
Validators.Add(myValidator);
}
}
Then, later on in the triggering control:
protected void myButton_Click(object sender, EventArgs e)
{
Page.Validate();
if (!Page.IsValid) { return; }
// validation passed, proceed...
}
Disclaimer: all of this is empirical, I haven't found MSDN docs to back it up, but it seems to work.

Elegant way to make CustomValidator work with ValidationSummary messagebox

I have run into this problem before but never quite solved it. I have a form with several validators and also a CustomValidator.
<asp:Label ID="lblMemberNum" runat="server" Text="Membership #:" CssClass="LabelMedium" ></asp:Label>
<asp:TextBox ID="txtMemberNum" runat="server" CssClass="TextBox" ></asp:TextBox>
<asp:RequiredFieldValidator ID="rfvMemberNum" SetFocusOnError="True" runat="server"
ControlToValidate="txtMemberNum" ErrorMessage="[ Membership # ] is required"
CssClass="ValidationMessage" Display="Dynamic" >*</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="revMemberNum" Display="Dynamic" runat="server"
ControlToValidate="txtMemberNum" CssClass="ValidationMessage"
ErrorMessage="[ Membership # ] can only contain letters"
ValidationExpression="^([a-zA-Z\d]+)$" >*</asp:RegularExpressionValidator>
<asp:CustomValidator ID="cvMemberNum" runat="server"
CssClass="ValidationMessage" Display="Dynamic"
ControlToValidate="txtMemberNum" ValidateEmptyText="false"
OnServerValidate="cvMemberNum_Validate"
ErrorMessage="This membership number is already registered">*</asp:CustomValidator>
<asp:ValidationSummary ID="ValidationSummary1" runat="server"
CssClass="ValidationMessage"
ShowMessageBox="True" ShowSummary="False" />
and on the server side:
protected void cvMemberNum_Validate(object source, ServerValidateEventArgs args)
{
try
{
args.IsValid = (!CampaignRegistration.IsMemberRegistered(args.Value));
}
catch
{
args.IsValid = false;
}
}
My problem is: The ValidationSummary never shows the message from CustomValidator. This question has been asked in several places, but I havent seen a satisfactory answer.
Try using a ValidationGroup property across all your validators and the ValidationSummary.
EDIT: Another possibility could be the Server Validation Code
args.IsValid = (!CampaignRegistration.IsMemberRegistered(args.Value));
if CampaignRegistration.IsMemberRegistered(args.Value) is returning false, "!" is making it true and therefore making it valid. I think you should get rid of the "!" as follows:
args.IsValid = CampaignRegistration.IsMemberRegistered(args.Value);
UPDATE: In order for the ValidationSummary to display your custom validator message in a messagebox, you need to have ClientValidationFunction Code. If you need to display just the summary without a popup, this is not needed.
<asp:CustomValidator ID="cvMemberNum" runat="server"
CssClass="ValidationMessage" Display="Dynamic"
ControlToValidate="txtMemberNum" ValidateEmptyText="false"
OnServerValidate="cvMemberNum_Validate"
ClientValidationFunction = "ClientValidate"
ErrorMessage="This membership number is already registered">*</asp:CustomValidator>
//JavaScript Code.
function ClientValidate(source, args)
{
args.IsValid = false; //you need to add validation logic here
}
MORE: If you don't want to do ClientSide Validation, try this trick to show the alert. Make this change to your CustomValidator ServerValidate method:
protected void cvMemberNum_Validate(object source, ServerValidateEventArgs args)
{
bool isValid = true;
try
{
isValid = (!CampaignRegistration.IsMemberRegistered(args.Value));
}
catch
{
isValid = false;
}
args.IsValid = isValid;
if(!isValid)
{
if(!Page.IsClientScriptBlockRegistered("CustomValidation"))
Page.RegisterClientScriptBlock("CustomValidation", "<script>alert('This membership number is already registered');</script>");
}
}
The ShowMessageBox option is fully client-side, so it will only evaluate if you have set the ClientValidationFunction on the CustomValidator.
You can also fake it by registering a script that makes an alert, so when you get back from the server's validation, it'll prompt with the error message. This can either be registered in the ServerValidate method (per #Jose Basilio), or you can call the following method during the PreRender event to register a popup with all invalid validators on the page:
/// <summary>
/// Registers a script to display error messages from server-side validation as the specified <see cref="UserControl"/> or <see cref="Page"/> loads from a postback.
/// </summary>
/// <remarks>
/// Must be called in the PreRender if used to validate against the Text property of DNNTextEditor controls, otherwise Text will not be populated.
/// Must set the ErrorMessage manually if using a resourcekey, otherwise the resourcekey will not have overridden the ErrorMessage property.
/// </remarks>
/// <param name="ctrl">The <see cref="UserControl"/> or <see cref="Page"/> which is being posted back.</param>
/// <param name="validationGroup">The validation group against which to validate.</param>
public static void RegisterServerValidationMessageScript(TemplateControl ctrl, string validationGroup)
{
if (ctrl != null && ctrl.Page.IsPostBack)
{
ctrl.Page.Validate(validationGroup);
if (!ctrl.Page.IsValid)
{
StringBuilder errorMessage = new StringBuilder("<script language='javascript'>alert('");
for (int i = 0; i < ctrl.Page.Validators.Count; i++)
{
IValidator validator = ctrl.Page.Validators[i];
if (!validator.IsValid)
{
errorMessage.Append("- " + validator.ErrorMessage);
if (i < ctrl.Page.Validators.Count - 1)
{
errorMessage.Append(#"\r\n");
}
}
}
errorMessage.Append("');</script>");
ctrl.Page.ClientScript.RegisterStartupScript(typeof(IValidator), "validationAlert", errorMessage.ToString(), false);
}
}
}
I've recently had same problem. ValidationSummary was not showing the ErrorMessage from CustomValidator when ServerValidate stated validation failure. Since by default (as my little reverse engineering showed) validation summary is rendered client side on postback I've simply added a script that checks all validators on document load/async postback completion and triggers validation summary creation for failed validation groups:
$(document).ready(function () {
var displayAlert = function () {
if (typeof Page_Validators == 'undefined') return;
var groups = [];
for (i = 0; i < Page_Validators.length; i++)
if (!Page_Validators[i].isvalid) {
if (!groups[Page_Validators[i].validationGroup]) {
ValidationSummaryOnSubmit(Page_Validators[i].validationGroup);
groups[Page_Validators[i].validationGroup] = true;
}
}
};
displayAlert();
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
function () {
displayAlert();
});
}
);
In my scenario I had nested user controls with validators, update panel and validation summary at the parent page.
More details here.
You should write a property
ValidationGroup="ValidationSummary1"
at every validator in your case.
Also check if your page has
AutoEventWireup="true"
bduke's RegisterServerValidationMessageScript is "faking it", but it isn't. It really fixes the problem. Every Utility namespace needs this function somewhere.
I have found a workaround for when javascript is disabled and the ValidationSummary does not show the errorMessage property of the CustomValidator. This is required as injecting script or alerts, as described above, will not work.
Add a new Validator control, let's call it CustomValidatorProxy, set its ControlToValidate property to any one of the controls on the form and EnableClientScript=false.
Within the ServerValidate event handler perform your custom validation and if validation fails set the IsValid property of the CustomValidator and CustomValidatorProxy to false and similarly set both ErrorMessage properties.
If the validation in the ServerValidate is passed ensure that the IsValid property of the CustomValidatorProxy is set to true.
Provided the CustomValidatorProxy is before the CustomValidator in the ValidatorCollection of the Page then the ServerValidate handler will override the IsValid property value that the CustomValidatorProxy would have returned having validated the ControlToValidate value and your ErrorMessage from your CustomValidator will be displayed in the ValidationSummary.
This worked for me:
<asp:CustomValidator runat="server" ID="cv"
ClientValidationFunction="ValidateFunction"
ErrorMessage="Default error
message">*</asp:CustomValidator>
<script type="text/javascript">
function ValidateFunction(sender, args)
{
var msg ='';
var formValid = true;
[various checks setting msg and formValid]
if (msg.length > 0) { sender.errormessage = msg; }
args.IsValid = formValid;
}
</script>

Resources