views:

3909

answers:

7

I have a question about what could stop a RequiredFieldValidator from preventing a postback.

I began working on an older, but simple aspx form and my predecessor used manual, server-side form validation (checking to see if some form fields have a value and if not displaying an error message in a label). I thought I'd clean out some unneeded code and replace the manual checking with RequiredFieldValidator controls, but while they appear to be validating, they aren't preventing a postback. Ie., I get my error messages displayed but the postback still occurs.

The form is quite simple and there are no CausesValidation="false" attributes set. My controls look like:

 <asp:TextBox ID="txtPhone" Runat="server" Columns="20" MaxLength="20" />
 <asp:RequiredFieldValidator ID="rfvPhone" runat="server" Display="Dynamic"
      ErrorMessage="* Required" ControlToValidate="txtPhone" />

I created a brand new webform in the same project with just a single textbox, validator and submit button and it acts the same way. Error message displays but postback still occurs.

Is there a global or project-wide setting that would cause this behaviour? Something in the web.config or global.asax?

A: 

Could you try an explicit EnableClientScript="True" parameter to the RequiredFieldValidator?

Adrian Grigore
+2  A: 

Validation can occur on the client if available, or on the server. The job of the validator isn't to prevent a postback, it's to validate the input.

Make sure that you have javascript enabled, and try explicitly setting "EnableClientScript" to true.

In the code-behind, you should never trust that the validators are validating on the client, and always use "if Page.IsValid".

womp
Hmm...I can and will change it to check if the form is valid, but I'm curious to know why this project is behaving differently than web projects I've created.
Dana
Any possibility your validator is programmatically being set to Visible="false", or your button clicks are calling form submits manually from javascript (thereby bypassing the DoPostBackWithOptions() client side call)?
womp
Nope -- I created a completely new form in the same project to test that and the new form exhibits the same behaviour.
Dana
A: 

If you press "Enter" inside a textbox to submit the form, I don't think the validators will prevent the postback.

David
+7  A: 

Whew. Okay, I found the problem, basically by creating a brand new project and comparing its web.config line-by-line with my old project. Turns out the culprit is this:

 <xhtmlConformance mode="Legacy"/>

If I remove the line, my validation works the way I expected it to. Googling that uncovered a bunch of blog posts about how VisualStudio adds that line to the web.config when upgrading web apps from .net 1.1 to .net 3.5.

The blog posts were mainly complaining about how that field interferes with .net's AJAX stuff, but I'm guessing it messes with the JavaScript emitted for the RequiredFieldValidator in a similar fashion.

Dana
Wow. Just... wow. How have I never run into this before? This is a huge issue because Server-side validation does not stop any events from firing, only sets the IsValid property. Basically, I've been coding ASP.NET wrong. :|
Bryan
This took me way longer than I care to admit to find as the cause of validation issues in our application.
Nick Josevski
A: 

Dana, You're a lifesaver. I was pulling my hair out over this one for the last few hours. The xhtmlConformance mode="Legacy" fixed everything. Thank you, thank you, thank you

Happy to help :) This is why stackoverflow is awesome!
Dana
Absolutely agree, better suited to a comment than an Answer though Zac.
TreeUK
A: 

Great solution about the mode="Legacy" it save me a lot of hours researching the "Why!?". Thx, Dana.

David
A: 

I had the same problem, but the answer turned out to be quite different. I was also upgrading to .NET validation from server-side hard coded validation.

The issue in my case turned out to be related to the ASP.NET rewriting engine used from the MSDN article URL Rewriting in ASP.NET. Using the default implementation of the "Actionless Form" was the culprit - apparently this one was written based off of an earlier version of .NET and the JavaScript on the form that prevented the postback was not being send to the output because it was missing code.

Anyway, in case anyone else is using this rewriting engine, the solution was to change the default implementation of ActionlessForm to the following:

Public Class Form
    Inherits System.Web.UI.HtmlControls.HtmlForm

    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
        MyBase.Render(New ActionlessFormHtmlTextWriter(writer))
    End Sub

End Class

Public Class ActionlessFormHtmlTextWriter
    Inherits HtmlTextWriter

    Sub New(ByVal writer As HtmlTextWriter)
        MyBase.New(writer)
        Me.InnerWriter = writer.InnerWriter
    End Sub

    Sub New(ByVal writer As System.IO.TextWriter)
        MyBase.New(writer)
        MyBase.InnerWriter = writer
    End Sub

    Public Overrides Sub WriteAttribute(ByVal name As String, ByVal value As String, ByVal fEncode As Boolean)

        Dim Context As HttpContext = HttpContext.Current

        'Skip the action attribute of the form control.
        If Not (name = "action") OrElse Not Context.Items("ActionAlreadyWritten") Is Nothing Then

            MyBase.WriteAttribute(name, value, fEncode)

        Else
            Context.Items("ActionAlreadyWritten") = True
        End If
    End Sub

End Class

What this does is simply supress the action attribute, but allow any other logic in the framework to run. This should future proof this in case Microsoft decides to change the form again.

NightOwl888