ASP.NET Selective Validation Hack

Scenario: using classic ASP.NET Web Forms, we have a data entry page. On the bottom of the page are two buttons: “Save Draft” and “Submit.”

When a user Saves a Draft, we want to do some validation, but not all. We want to make sure only numbers are entered for numeric fields, yet we don’t need all required fields to be filled out. But when a user Submits the document, all validation should occur.

ASP.NET doesn’t support this very nice. Validation Groups get us close, but are meant to work on completely different sets of validators. In our case, one set of validators is a subset of the other. Things get especially dicey if you throw a ValidationSummary onto the page.

With one JavaScript hack that can go in your Master Page you can get the desired behavior. First, the ASP.NET markup:

<span class="kwrd">&lt;</span><span class="html">p</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">asp:ValidationSummary</span> <font style="background-color: #ffff00"><span class="attr">ValidationGroup</span><span class="kwrd">="*"</span></font> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">p</span><span class="kwrd">&gt;</span>

<span class="kwrd">&lt;</span><span class="html">asp:TextBox</span> <span class="attr">ID</span><span class="kwrd">="SomeNumber"</span> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;</span><span class="html">asp:RequiredFieldValidator</span> <font style="background-color: #ffff00"><span class="attr">ValidationGroup</span><span class="kwrd">="Submit"</span></font>
    <span class="attr">Text</span><span class="kwrd">="Required"</span> <span class="attr">ErrorMessage</span><span class="kwrd">="SomeNumber is required."</span>
    <span class="attr">ControlToValidate</span><span class="kwrd">="SomeNumber"</span> <span class="attr">Display</span><span class="kwrd">="Dynamic"</span>
    <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;</span><span class="html">asp:RangeValidator</span> <span class="attr">Type</span><span class="kwrd">="Integer"</span> <span class="attr">MinimumValue</span><span class="kwrd">="0"</span> <span class="attr">MaximumValue</span><span class="kwrd">="100"</span>
    <span class="attr">Text</span><span class="kwrd">="Number"</span> <span class="attr">ErrorMessage</span><span class="kwrd">="SomeNumber must be [0, 100]."</span>
    <span class="attr">ControlToValidate</span><span class="kwrd">="SomeNumber"</span> <span class="attr">Display</span><span class="kwrd">="Dynamic"</span>
    <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>

<span class="kwrd">&lt;</span><span class="html">p</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">asp:Button</span> <span class="attr">Text</span><span class="kwrd">="Save Draft"</span> <span class="attr">onclick</span><span class="kwrd">="OnSaveDraft"</span> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">asp:Button</span> <span class="attr">Text</span><span class="kwrd">="Submit"</span> <span class="attr">onclick</span><span class="kwrd">="OnSubmit"</span> <font style="background-color: #ffff00"><span class="attr">ValidationGroup</span><span class="kwrd">="Submit"</span></font> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">p</span><span class="kwrd">&gt;</span>

Then drop this near the bottom of your Page or Master Page:

&lt;script type=<span class="str">"text/javascript"</span>&gt;
<span class="rem">// Override this part of ASP.NET validation in order to make validation</span>
<span class="rem">// groups work as subsets of each other rather than completely independently.</span>
<span class="kwrd">function</span> IsValidationGroupMatch(control, validationGroup) {
    <span class="kwrd">if</span> ((<span class="kwrd">typeof</span> (validationGroup) == <span class="str">"undefined"</span>) || (validationGroup == <span class="kwrd">null</span>)) {
        <span class="kwrd">return</span> <span class="kwrd">true</span>;
    }
    <span class="kwrd">var</span> controlGroup = <span class="str">""</span>;
    <span class="kwrd">if</span> (<span class="kwrd">typeof</span> (control.validationGroup) == <span class="str">"string"</span>) {
        controlGroup = control.validationGroup;
    }
    <span class="kwrd">return</span> (controlGroup == validationGroup<font style="background-color: #ffff00"><strong> || controlGroup == <span class="str">'*'</span> || validationGroup.length &gt; 0</strong></font>);
}    
&lt;/script&gt;

The method IsValidationGroupMatch() is supplied by ASP.NET client-side validation. We override that method and add the highlighted bit to it.

Caveat 1: This won’t affect server-side validation, so to be thorough the OnSubmit in the code behind should have at the top, Validate(“”); if(!Page.IsValid) return;

Caveat 2: This will probably cause problems if you want to use Validation Groups in the way they were originally intended, as completely isolated sets of validators.

This entry was posted in Programming. Bookmark the permalink.