Server Side Custom Validator Not Firing - asp.net

I'm having an odd problem in that one of the 4 custom validators on my web page is not firing. Everything looks correct based on the working validators. Below is the simplified code.
ASPX code -
<asp:TextBox ID="CMT_TXT" runat="server" Columns="60" Rows="8"
TextMode="MultiLine" Text='<%#Eval("CMT_TXT")%>'></asp:TextBox><br />
<asp:CustomValidator ID="csvCMT_TXT" runat="server" ControlToValidate="CMT_TXT"
Display="Dynamic" EnableClientScript="False" ErrorMessage="Msg">
</asp:CustomValidator>
VB code -
Public Sub csvCMT_TXT_ServerValidate(source As Object,
args As ServerValidateEventArgs) _
Handles csvCMT_TXT.ServerValidate
dim s As String = CMT_TXT.Text
args.IsValid = s.Length <= 3500
End Sub
When testing,
The contents of field CMT_TXT has approximately 3000 characters. So it is not an empty field issue.
Page.Validate is called in the main body of the code

for server side validation to fire you need to call Page.Validate, this should trigger all your server side validation and update Page.IsValid
Also it does not look like you have the event set up on the custom val. may want to add the prop OnServerValidate
OnServerValidate="csvCMT_TXT_ServerValidate"
<asp:CustomValidator ID="csvCMT_TXT" runat="server" ControlToValidate="CMT_TXT"
Display="Dynamic" EnableClientScript="False" ErrorMessage="Msg" OnServerValidate="csvCMT_TXT_ServerValidate">
</asp:CustomValidator>

I'm not too familiar with VB.NET, but with C# I'll check the Page.IsValid field before continuing on with a page that has a CustomValidator.
An example with a Wizard control that contains a CustomValidator in the final stage, I will check this value in the FinishButtonClick event.
protected void Wizard1_FinishButtonClick(object sender, WizardNavigationEventArgs e)
{
if (Page.IsValid == false)
{
// validator failed, stop wizard from continuing
return;
}
// page is valid, continue on
// ...
}
Not sure if there are any differences with VB.NET, but may be worth a shot

At a glance, it looks like you named your handler incorrectly. The control ID is csvCMT_TXT while the handler is csv_CMT_TXT.ServerValidate. There's an extra _ in the handler.

The problem turned out to be a problem with the VS2010 project build.
To this the problem, I had to
Deleted all files in BIN directory
Deleted all file in OBJ directory
Deleted Custom Validator
Rebuilt the Project
Add Custom Validation back into program. Added the original code back into program
It's a bit extreme, but this is what it took to resolve the problem.

Related

asp:textbox calling asp:button handler on text change

I have the most bizarre problem happening ... I'm controlling a menu edit page and I have a series of controls, an asp:textbox with the numeric ID of the menu being worked on, flanked by - and + buttons to decrement and increment the ID. The user can type a new index in the textbox, or use the buttons. Easy peasy, right?
Here's the ASPX markup:
<asp:Button id="menuDown" runat="server" CausesValidation="false" OnClick="DownClick" Text="-" />
Menu # <asp:textbox runat="server" MaxLength="5" Columns="3" id="tbMenuId" />
<asp:Button id="menuUp" runat="server" CausesValidation="false" OnClick="UpClick" Text="+" />
There's a CompareValidator further down the page ensuring a non-negative, numeric entry.
Over in my code behind, my Page_Load pulls the value out of the textbox without problems:
Try
menuId = Integer.Parse(tbMenuId.Text)
Catch
menuId = 0
tbMenuId.Text = "0"
End Try
This works great (with ONE caveat) — every time I change the menu ID via the textbox, after the Page_Load method pulls the new value out of the text box perfectly, the DownClick handler gets called, decrementing the desired ID.
So far, the ONLY way I've managed to have the requested menu appear is to eliminate the two asp:Button controls. Eliminating only the menuDown button causes the UpClick handler to get called.
I had an OnTextChanged="..." attribute on the asp:Textbox control, but that handler NEVER got called and didn't seem necessary anyway, so I pulled it.
I cannot help but think the two behaviors must be connected.
Anyone understand WHY this is happening?
This qualifies as hacky work-around, rather than a fix, but it does let me proceed forward until this behavior can be explained.
The OnTextChanged event is firing the way it's supposed to now (not sure what I did wrong the first time) so, I used it to implement the hackiest of hacks ...
Protected Property hackyFlag As Boolean ' Suppress button click (true) after text change
' ... value in session variable
Protected Sub tbMenuId_TextChanged(sender As Object, e As EventArgs)
Integer.TryParse(tbMenuId.Text, menuId)
hackyFlag = True
End Sub
Protected Sub DownClick(sender As Object, e As EventArgs)
If hackyFlag Then : hackyFlag = False : Return : End If
If menuId > 0 Then menuId -= 1
tbMenuId.Text = menuId
End Sub
Gross, hacky, and disgusting ... but it works. :-) The button handler is still being called incorrectly, but now it's smart enough to do what I want instead of what the framework is telling it to do.
Still open to better answers and/or explanations as to why this is happening on this page and hasn't happened on any other. ( knock on wood )

Showing single error for multiple asp validators

I have a text box control in asp with 3 different validators. Each validator is getting its error message from the server, and each one validates different things.
My problem is that for some values, two or more validators are firing and I'm getting more then one error message.
I would like to make some kind of priority functionality, meaning that if the first validator is firing the other two will not. Is there any way to make the validator behave like that?
I've added some code sample:
<asp:RequiredFieldValidator ID="cvRequired" runat="server" Display="Dynamic"
ControlToValidate="txtBox" />
<asp:RegularExpressionValidator ID="cvFormat" runat="server" Display="Dynamic"
ControlToValidate="txtBox" ValidationExpression="^([A-Za-z])+$" />
<asp:CustomValidator ID="cvCustom" runat="server" Display="Dynamic"
ControlToValidate="txtBox" ClientValidationFunction="validateFunction" />
I want that the format validator and the custom validator will not fire if the required validator is invalid (actually, I just want them to not showing their error message).
As I said, the error messages are from the server, so I can't really join them to one custom validator. Also, the "validateFunction" is in another js file (for re-use).
Few logic options you got to think about,
(txtPhone) having three validators.
1.RangeValidator, 2.CustomValidator 3.Regexvalidator
Say,after validation (check what it returns if validation fails/passes) and act upon that.
if(rangevalidator1 != null)
{
...somecode...
}
I ll suggest you using javascript ..
you can use a single custom validator for all three validation and you put your code in if condition according to your need.
<asp:CustomValidator runat="server" ID="cstmStartDateValidater"
ToolTip="Start date cannot be greater than equal to end date/time or less than current date/time"
ErrorMessage="*" ControlToValidate="txtStartDateTime"
ForeColor="Red" ValidationGroup="vlgMessage" SetFocusOnError="true"
onservervalidate="cstmStartDateValidater_ServerValidate" ></asp:CustomValidator>
in the .cs page
protected void cstmStartDateValidater_ServerValidate(object source, ServerValidateEventArgs args)
{
if (CompareStartDate())
{
args.IsValid = true;
}
else
{
args.IsValid = false;
}
}
you can use following link for more information :
MSDN,
Code Project
hope these will help you .
Make use of ValidatorCalloutExtender control which is available in ajax control toolkit.
Place a separate ValidatorCalloutExtender across each control,you wish to validate it.

UpdatePanel resetting object to inital state

I have an application that I am currently writing that works by iterating through nodes, and then updating the page with the information of the current node. I have an UpdatePanel in the page which contains a label, textbox, and a button. The label lists the currently available children of the current node, the user enters in which child they want to go to into the textbox, and then hits the submit button. I set the new value of the node in the submit button's event handler.
Here's my problem: Every time I enter in which node I want to navigate to, the object resets its value to the value it was initially initialized to. I have even put this same code into a Windows Form to validate that it's working correctly to iterate through my tree, and it works as it should, so I know my problem is AJAX-related.
This is the first app that I have written using AJAX, so I am still in the process of learning how it works. Any help would be greatly appreciated. I have Googled and searched SO through and through.
Here is the HTML:
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="question" runat="server" Text=""></asp:Label>
<br />
<asp:TextBox ID="answer" runat="server"></asp:TextBox>
<br />
<asp:Button ID="Submit" runat="server" Text="Submit" onclick="Submit_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
And the C#:
protected void Submit_Click(object sender, EventArgs e)
{
int ans = int.Parse(answer.Text);
if (!current.ChildIDs.Contains(ans))
{
return;
}
current = tree.Node(ans);
question.Text = current.Question;
}
current is the current node, which has a public ArrayList of all of its children's IDs. tree is the NodeTree I have; calling Node just returns the new node. Both current and Tree get initialized in the Page_Load event, and that only fires once (when the page is first loaded).
It's really pretty simply code; I'm just having difficulty understanding why the AJAX isn't working correctly.
I have even put this same code into a
Windows Form to validate that it's
working correctly to iterate through
my tree, and it works as it should, so
I know my problem is AJAX-related.
It sounds like you're expecting ASP.NET to remember what the object current is between requests, since that's how Windows forms applications work.
Web applications are stateless - after each request, ASP.NET discards all your variables. To access the variable during a subsequent request, you have to either:
1) Send enough data with the request to reconstruct the variable. You can do this using a querystring parameter or an HTML form value (the hidden fields another response mentioned).
2) Save the variables in a Session store (which can be in-memory or backed by a database).
3) Store the value in a coookie.
Of these three, it's easiest to show you how to use Session, given what you've shared in your question. However, beware: session has its risks - by default, ASP.NET session objects are stored in-memory, and it's a potential security hazard. But here's how you should be able to get your application to work.
// In your Page_Load code that initializes your 'current' variable
// When the user first requests the page, create a new Node
if (! this.IsPostBack)
{
Node current = new Node(); //
Session("currentNode") = current;
}
// When the user clicks a button on the page (posts), use the
// node in session instead
else
{
current = Session("currentNode");
}
When you update non-form elements in the browser (labels, literals, etc.), .NET is unable to see any of the changes you've made.
Try adding a hidden input for each label that records the new value. Then within the method you have wired up to the button's OnClick event, do something like this:
myLabel.Text = myHiddenInput.value;
I think you just need to tell the updatepanel to update itself. Try this:
protected void Submit_Click(object sender, EventArgs e)
{
int ans = int.Parse(answer.Text);
if (!current.ChildIDs.Contains(ans))
{
return;
}
current = tree.Node(ans);
question.Text = current.Question;
UpdatePanel.Update();
}

ASP.Net CustomValidator in GridView is not fired

I got a Gridview in an UpdatePanel with this EditTemplate:
<edititemtemplate>
<asp:textbox id="txtDistFrom" runat="server" text='<%# Bind("distFrom") %>' width="30" />
<asp:CustomValidator ID="valDistFrom" ValidateEmptyText="True" OnServerValidate="valDistFromTo_ServerValidate" ControlToValidate="txtDistFrom" Text="Missing" ToolTip="Invalid" Display="Dynamic" runat="server" />
</edititemtemplate>
And a simple Server-side function:
Protected Sub valDistFromTo_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs)
Dim cv As CustomValidator = CType(source, CustomValidator)
Dim gvr As GridViewRow = cv.NamingContainer
Dim tbV As UI.WebControls.TextBox = gvr.FindControl("txtDistFrom")
If tbV.Text <> "" Then
args.IsValid = False
cv.ErrorMessage = "inhalt ist " & tbV.Text
End If
End Sub
But when debugging this code the server-side function is not fired, whatever it does. It seems it has to do with the gridview, so I cannot access the control directly by its id. Any suggestions?
If you modify your VB to:
Protected Sub valDistFromTo_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs)
Dim cv As CustomValidator = CType(source, CustomValidator)
If args.Value <> "" Then
args.IsValid = False
cv.ErrorMessage = "inhalt ist " & args.Value
End If
End Sub
It should work. Note that I'm using args.Value. I use CustomValidators and TextBox within EditTemplates with ControlToValidate set to the TextBox ID all the time and it works, you just can't get the TextBox object the way you're trying it. I think this is far less of a pain and much cleaner than messing around with RowUpdating Event as suggested in TGnat's answer.
In this case you can use a required field validator. Which should work just fine in a grid.
For server side validation I would move the custom validator outside the grid entirely and leave the ControlToValidate property blank. You can move your validation to the RowUpdating event of the grid and set any error messages on the custom validator. Rmember to set the validators IsValid property appropriately.
The problem is related to the ControlToValidate property, because the ID of your text box is not used in repeating elements like GridView, ListView and Repeater. In other words: You have stumbled upon a limitation in ASP.NET's engine.
I am not sure how to solve this problem, though. You might be able do it, by adding the CustomValidator programmatically by attaching a method to the GridView's OnRowBound method.
This article might provide an answer This article might provide an answer: Integrating Asp.Net Validation Controls with GridView at run-time.
I also tend to think that ControlToValidate is the problem. .NET changes the ID of that control at runtime and the custom validator probably isn't picking it up.
I would try adding the customvalidator on RowCreated or RowDatabound using the FindControl()
I had the same problem. When I explicitly set this property in my customvalidator, the server side code fired:
EnableClientScript="false"

ASP.NET Page Validation

Related Article
On a similar topic to the above article, but of a more specific note. How exactly do you handle items that are in the viewstate (so they are included on submit), but can also be changed via AJAX. For instance, say we had a dropdown list that was populated through an AJAX web service call (not an update panel). How can I get the page to validate once the dropdownlist's items have been changed?
You're not validating the dropdown list are you? You're validating the value a user selected. It's pretty much the same advice as the other post, since javascript or other tools can alter the html or create their own POST's, you must always validate on the server side. Assume all client requests can be tampered with, and assume that no client-side validation has occurred.
If you're using the web forms model ....
If you just want to check a value was selected in the dropdown myAjaxDropDown, use the
<asp:RequiredFieldValidator id="dropdownRequiredFieldValidator"
ControlToValidate="myAjaxDropDown"
Display="Static"
InitialValue="" runat=server>
*
</asp:RequiredFieldValidator>
You could also want to look at the asp:CustomValidator - for server side validation:
<asp:CustomValidator ID="myCustomValidator" runat="server"
onservervalidate="myCustomValidator_ServerValidate"
ErrorMessage="Bad Value" />
Both plug into the validation framework of asp.net. e.g. when you click a button called SumbitButton
protected void myCustomValidator_ServerValidate(object source, ServerValidateEventArgs e)
{
// determine validity for this custom validator
e.IsValid = DropdownValueInRange(myAjaxDropDown.SelectedItem.Value);
}
protected void SubmitButton_Click( object source, EventArgs e )
{
Validate();
if( !IsValid )
return;
// validators pass. Continue processing.
}
Some links for further reading:
ASP.Net 2.0 Quickstart - Validating Form Input Controls
ASP.NET Validation Controls – Important Points, Tips and Tricks
You can call the Page_Validate() function from your javascript code, it will trigger the asp.net validators on the page, it is basically similar to Page.Validate() in server code
why not validating onChange even in the dropdownlist?
just add the script manager and add that property to the onchange in the Page_Load event
' Creating the javascript function to validate
Dim js As String
js = "function validateDDL1(ddl) { alert(ddl.value); }"
' Adding onChange javascript method
DropDownList1.Attributes.Add("onchange", "validateDDL1(this);")
' Registering the javascript
ScriptManager.RegisterClientScriptBlock(Me, GetType(String), "validateDDL1(ddl)", js, True)

Resources