<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>jrummell.ToString() &#187; xval-webforms</title>
	<atom:link href="http://www.jrummell.com/blog/index.php/tag/xval-webforms/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jrummell.com/blog</link>
	<description>another .NET blog</description>
	<lastBuildDate>Sat, 13 Aug 2011 00:14:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>xVal for WebForms without xVal</title>
		<link>http://www.jrummell.com/blog/index.php/2011/06/xval-for-webforms-without-xval/</link>
		<comments>http://www.jrummell.com/blog/index.php/2011/06/xval-for-webforms-without-xval/#comments</comments>
		<pubDate>Mon, 06 Jun 2011 03:23:44 +0000</pubDate>
		<dc:creator>jrummell</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[xval-webforms]]></category>

		<guid isPermaLink="false">http://www.jrummell.com/blog/index.php/2011/06/xval-for-webforms-without-xval/</guid>
		<description><![CDATA[I’ve been working on xVal for WebForms without xVal in the jQuery.Validate branch. So far I’ve got basic server and client side validation for most data annotations validation attributes and server side validation for IValidatableObject implementers. The only challenging part so far was understanding how to serialize the validation rules for the jQuery Validate add [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>I’ve been working on <a href="http://xvalwebforms.codeplex.com/" target="_blank">xVal for WebForms</a> without xVal in the <a href="http://xvalwebforms.codeplex.com/SourceControl/list/changesets?branch=jQuery.Validate" target="_blank">jQuery.Validate</a> branch. So far I’ve got basic server and client side validation for most data annotations validation attributes and server side validation for <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.ivalidatableobject.aspx" target="_blank">IValidatableObject</a> implementers. The only challenging part so far was understanding how to serialize the validation rules for the jQuery Validate <a href="http://docs.jquery.com/Plugins/Validation/rules" target="_blank">add method</a>.</p>
<pre class="csharpcode">$(<span class="str">&quot;#txtClientName&quot;</span>).rules(<span class="str">&quot;add&quot;</span>, {
 required: <span class="kwrd">true</span>,
 minlength: 5,
 messages: {
   required: <span class="str">&quot;Client name is required.&quot;</span>,
   minlength: <span class="str">&quot;Client name must be at least 5 characters.&quot;</span>
 }
});</pre>
<p>I finally decided to implement JavaScriptConverter, which is used with JavaScriptSerializer. The Serialize method is what takes the Rule collection and converts it into two separate dictionaries, one for rules and one for messages. This allows the JavaScriptSerializer to properly serialize the dictionaries for the add method options parameter.</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> RulesJavaScriptConverter : JavaScriptConverter
{
    <span class="kwrd">private</span> <span class="kwrd">readonly</span> ReadOnlyCollection&lt;Type&gt; _supportedTypes =
        <span class="kwrd">new</span> ReadOnlyCollection&lt;Type&gt;(<span class="kwrd">new</span> List&lt;Type&gt;(<span class="kwrd">new</span>[] {<span class="kwrd">typeof</span> (RuleCollection)}));

    <span class="kwrd">public</span> <span class="kwrd">override</span> IEnumerable&lt;Type&gt; SupportedTypes
    {
        get { <span class="kwrd">return</span> _supportedTypes; }
    }

    <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">object</span> Deserialize(IDictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">object</span>&gt; dictionary, Type type,
                                       JavaScriptSerializer serializer)
    {
        <span class="kwrd">throw</span> <span class="kwrd">new</span> NotSupportedException();
    }

    <span class="kwrd">public</span> <span class="kwrd">override</span> IDictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">object</span>&gt; Serialize(<span class="kwrd">object</span> obj, JavaScriptSerializer serializer)
    {
        <span class="kwrd">return</span> Serialize(obj <span class="kwrd">as</span> RuleCollection, serializer);
    }

    <span class="kwrd">public</span> IDictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">object</span>&gt; Serialize(RuleCollection rules, JavaScriptSerializer serializer)
    {
        <span class="kwrd">if</span> (rules == <span class="kwrd">null</span>)
        {
            <span class="kwrd">throw</span> <span class="kwrd">new</span> ArgumentNullException(<span class="str">&quot;rules&quot;</span>);
        }

        Dictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">object</span>&gt; options =
            rules.ToDictionary&lt;Rule, <span class="kwrd">string</span>, <span class="kwrd">object</span>&gt;(rule =&gt; rule.Name, rule =&gt; rule.Options);
        Dictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">string</span>&gt; messages =
            rules.ToDictionary(rule =&gt; rule.Name, rule =&gt; rule.Message);

        Dictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">object</span>&gt; result =
            <span class="kwrd">new</span> Dictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">object</span>&gt;(options) {{<span class="str">&quot;messages&quot;</span>, messages}};

        <span class="kwrd">return</span> result;
    }
}</pre>
<p>And here&#8217;s how I’m using it.</p>
<pre class="csharpcode">StringBuilder validationOptionsScript = <span class="kwrd">new</span> StringBuilder();
validationOptionsScript.AppendFormat(<span class="str">&quot;$('#{0}').rules('add', &quot;</span>, _controlToValidateId);

JavaScriptSerializer serializer = <span class="kwrd">new</span> JavaScriptSerializer();
serializer.RegisterConverters(<span class="kwrd">new</span>[] {<span class="kwrd">new</span> RulesJavaScriptConverter()});
serializer.Serialize(rules, validationOptionsScript);

validationOptionsScript.AppendLine(<span class="str">&quot;);&quot;</span>);</pre>
<p>The next step will be figuring out validation groups. I also plan on renaming the project. My best idea so far is jQuey Validate.NET. It’s not the most creative, but it gets the point across.</p>
<div class="shr-publisher-188"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jrummell.com/blog/index.php/2011/06/xval-for-webforms-without-xval/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>xVal for WebForms &#8211; the Future</title>
		<link>http://www.jrummell.com/blog/index.php/2011/05/xval-for-webforms-the-future/</link>
		<comments>http://www.jrummell.com/blog/index.php/2011/05/xval-for-webforms-the-future/#comments</comments>
		<pubDate>Tue, 03 May 2011 19:47:01 +0000</pubDate>
		<dc:creator>jrummell</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[validation]]></category>
		<category><![CDATA[xval-webforms]]></category>

		<guid isPermaLink="false">http://www.jrummell.com/blog/?p=185</guid>
		<description><![CDATA[Based on comments I&#8217;ve received from my last xVal for WebForms post, I&#8217;ve decided on a direction. The project will keep jQuery Validation but will move away from the xVal dependency. We&#8217;ll be trying the approach outlined by Dave Ward at Encosia.]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Based on comments I&#8217;ve received from my last <a title="The State of xVal for WebForms" href="http://www.jrummell.com/blog/index.php/2011/03/the-state-of-xval-for-webforms/">xVal for WebForms post</a>, I&#8217;ve decided on a direction. The project will keep jQuery Validation but will move away from the xVal dependency. We&#8217;ll be trying the approach outlined by Dave Ward at <a href="http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/">Encosia</a>.</p>
<div class="shr-publisher-185"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jrummell.com/blog/index.php/2011/05/xval-for-webforms-the-future/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The State of xVal for WebForms</title>
		<link>http://www.jrummell.com/blog/index.php/2011/03/the-state-of-xval-for-webforms/</link>
		<comments>http://www.jrummell.com/blog/index.php/2011/03/the-state-of-xval-for-webforms/#comments</comments>
		<pubDate>Sun, 06 Mar 2011 21:19:05 +0000</pubDate>
		<dc:creator>jrummell</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[validation]]></category>
		<category><![CDATA[xval-webforms]]></category>

		<guid isPermaLink="false">http://www.jrummell.com/blog/?p=136</guid>
		<description><![CDATA[I’ve been neglecting xVal for WebForms for a while now, mainly because I’m not sure which direction to take it. The xVal project is now deprecated in favor of the client side validation support introduced in ASP.NET MVC 2. This is obviously a problem since xVal for WebForms is built on top of xVal. I [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>I’ve been neglecting <a href="http://xvalwebforms.codeplex.com/" target="_blank">xVal for WebForms</a> for a while now, mainly because I’m not sure which direction to take it. The <a href="http://xval.codeplex.com/" target="_blank">xVal</a> project is now deprecated in favor of the client side validation support introduced in ASP.NET MVC 2. This is obviously a problem since xVal for WebForms is built on top of xVal.</p>
<p>I think there are a few directions the project could take. The more traditional WebForms approach would be to simply generate the standard System.Web.Web.UI validation controls based on a model’s DataAnnotation attributes. I’m a fan of this approach as it makes a lot of sense to WebForm developers. For example, consider the following model:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Booking
{
    [Required(ErrorMessage = <span class="str">"Client Name is required."</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> ClientName { get; set; }

    [Range(1, 20, ErrorMessage = <span class="str">"Number of Guests must be between 1 and 20."</span>)]
    <span class="kwrd">public</span> <span class="kwrd">int</span> NumberOfGuests { get; set; }
}</pre>
<p>&nbsp;</p>
<p>The generated validators would be very similar to the following:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">asp:RangeValidator</span> <span class="attr">ID</span><span class="kwrd">="valNumberOfGuests"</span> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="attr">Display</span><span class="kwrd">="Dynamic"</span>
<span class="attr">ControlToValidate</span><span class="kwrd">="txtNumberOfGuests"</span> <span class="attr">Type</span><span class="kwrd">="Integer"</span> <span class="attr">MinimumValue</span><span class="kwrd">="1"</span> <span class="attr">MaximumValue</span><span class="kwrd">="20"</span>
<span class="attr">ErrorMessage</span><span class="kwrd">="Number of Guests must be between 1 and 20."</span><span class="kwrd">/&gt;</span>

<span class="kwrd">&lt;</span><span class="html">asp:RequiredFieldValidator</span> <span class="attr">ID</span><span class="kwrd">="valClientName"</span> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="attr">Display</span><span class="kwrd">="Dynamic"</span>
<span class="attr">ControlToValidate</span><span class="kwrd">="txtClientName"</span> <span class="attr">ErrorMessage</span><span class="kwrd">="Client Name is required."</span> <span class="kwrd">/&gt;</span></pre>
<p>&nbsp;</p>
<p>The other option is to find a way use the ASP.NET MVC validation bits with WebForms. ASP.NET MVC 2 uses the MicrosoftAjax library, while ASP.NET MVC 3 introduced unobtrusive validation with jQuery Validate. This approach would work a lot like the current project, but it would utilize MVC instead of xVal. I have to admit I’m not thrilled about referencing System.Web.Mvc in a WebForms project.</p>
<p>Yet another option is to generate jQuery validation scripts from scratch, using the methods <a href="http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/" target="_blank">Dave Ward</a> has suggested. I like this idea since it doesn’t put a dependency on MVC bits.</p>
<p>It took me a while, but after working with WebForms and trying to make validation better, i.e. more like MVC, I can’t help but think that the best option is to simply move to MVC. But xVal for WebForms can still help projects that can’t be converted to MVC. I’ve already created a <a href="http://xvalwebforms.codeplex.com/SourceControl/list/changesets?branch=nativeWebFormValidation" target="_blank">branch</a> prototyping the first, most WebForms friendly option. <strong>If you use xVal for WebForms or are interested in attribute based client and server side validation, please let me know which option you would prefer.</strong></p>
<div class="shr-publisher-136"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jrummell.com/blog/index.php/2011/03/the-state-of-xval-for-webforms/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>xVal with WebForms Part 2</title>
		<link>http://www.jrummell.com/blog/index.php/2009/08/xval-with-webforms-part-2/</link>
		<comments>http://www.jrummell.com/blog/index.php/2009/08/xval-with-webforms-part-2/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 02:17:01 +0000</pubDate>
		<dc:creator>jrummell</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[validation]]></category>
		<category><![CDATA[xval-webforms]]></category>

		<guid isPermaLink="false">/john/blog/post/xVal-with-WebForms-Part-2.aspx</guid>
		<description><![CDATA[Since my last post, I’ve completely rethought and re-implemented my take on xVal for WebForms. If you’re not familiar with xVal, stop now and read the tutorial. Now that you’re back, lets talk about xVal and WebForms. Model This is the model we’ll be using (you should recognize it from the xVal tutorial): public class [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Since my <a href="http://john.rummell.info/john/blog/post/xVal-with-WebForms.aspx">last post</a>, I’ve completely rethought and re-implemented my take on <a href="http://xval.codeplex.com/" target="_blank">xVal</a> for WebForms. If you’re not familiar with xVal, stop now and read the <a href="http://blog.codeville.net/2009/01/10/xval-a-validation-framework-for-aspnet-mvc/" target="_blank">tutorial</a>. Now that you’re back, lets talk about xVal and WebForms.</p>
<h2>Model</h2>
<p>This is the model we’ll be using (you should recognize it from the xVal tutorial):</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Booking
{
    [Required]
    [StringLength(15)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> ClientName { get; set; }

    [Range(1, 20)]
    <span class="kwrd">public</span> <span class="kwrd">int</span> NumberOfGuests { get; set; }

    [Required]
    [DataType(DataType.Date)]
    <span class="kwrd">public</span> DateTime ArrivalDate { get; set; }
}</pre>
<h2>Form</h2>
<p>And here is the form:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">asp:ValidationSummary</span> <span class="attr">ID</span><span class="kwrd">=&quot;valSummary&quot;</span> <span class="attr">runat</span><span class="kwrd">=&quot;server&quot;</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;</span><span class="html">label</span> <span class="attr">for</span><span class="kwrd">=&quot;txtClientName&quot;</span><span class="kwrd">&gt;</span>
    Your name:<span class="kwrd">&lt;/</span><span class="html">label</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">=&quot;txtClientName&quot;</span> <span class="attr">runat</span><span class="kwrd">=&quot;server&quot;</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;</span><span class="html">label</span> <span class="attr">for</span><span class="kwrd">=&quot;txtNumberOfGuests&quot;</span><span class="kwrd">&gt;</span>
    Number of guests:<span class="kwrd">&lt;/</span><span class="html">label</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">=&quot;txtNumberOfGuests&quot;</span> <span class="attr">runat</span><span class="kwrd">=&quot;server&quot;</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;</span><span class="html">label</span> <span class="attr">for</span><span class="kwrd">=&quot;txtArrivalDate&quot;</span><span class="kwrd">&gt;</span>
    Arrival date:<span class="kwrd">&lt;/</span><span class="html">label</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">=&quot;txtArrivalDate&quot;</span> <span class="attr">runat</span><span class="kwrd">=&quot;server&quot;</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;</span><span class="html">asp:Button</span> <span class="attr">ID</span><span class="kwrd">=&quot;btnSubmit&quot;</span> <span class="attr">runat</span><span class="kwrd">=&quot;server&quot;</span> <span class="attr">Text</span><span class="kwrd">=&quot;Submit&quot;</span> <span class="attr">OnClick</span><span class="kwrd">=&quot;btnSubmit_Click&quot;</span> <span class="kwrd">/&gt;</span></pre>
<h2>ModelValidator</h2>
<p>My first try at validation was adding a validator control for each input field. After playing with it a bit, I decided that it would be better to have one validator for the entire model. This control defines the model’s type (ModelType), and then maps each property (PropertyName) to an input control (ControlToValidate).</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">val:ModelValidator</span> <span class="attr">ID</span><span class="kwrd">=&quot;valBooking&quot;</span> <span class="attr">runat</span><span class="kwrd">=&quot;server&quot;</span> <span class="attr">ModelType</span><span class="kwrd">=&quot;xVal.WebForms.Demo.Booking, xVal.WebForms.Demo&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">ModelProperties</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">val:ModelProperty</span> <span class="attr">PropertyName</span><span class="kwrd">=&quot;ClientName&quot;</span> <span class="attr">ControlToValidate</span><span class="kwrd">=&quot;txtClientName&quot;</span> <span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">val:ModelProperty</span> <span class="attr">PropertyName</span><span class="kwrd">=&quot;NumberOfGuests&quot;</span> <span class="attr">ControlToValidate</span><span class="kwrd">=&quot;txtNumberOfGuests&quot;</span> <span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">val:ModelProperty</span> <span class="attr">PropertyName</span><span class="kwrd">=&quot;ArrivalDate&quot;</span> <span class="attr">ControlToValidate</span><span class="kwrd">=&quot;txtArrivalDate&quot;</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">ModelProperties</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">val:ModelValidator</span><span class="kwrd">&gt;</span></pre>
<h2>ControlToValidate</h2>
<p>The biggest challenge was figuring out how to reference the input controls by given ID instead of by the elementPrefix + PropertyName convention. In other words, MVC xVal assumes that your ClientName input control ID is booking.ClientName, where booking is the elementPrefix and ClientName is the name of the property. This doesn’t work out so well with web forms and generated IDs. I got around this with the ModelProperties collection of ModelValidator. Then I updated the json formatted rule script to include each property’s control ID.</p>
<h2>Complete Source and Demo</h2>
<p>Get the <a href="http://xvalwebforms.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=31487" target="_blank">complete source</a> (with Bookings demo) at the <a href="http://xvalwebforms.codeplex.com/" target="_blank">xVal.WebForms</a> project page on CodePlex.</p>
<div class="shr-publisher-15"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jrummell.com/blog/index.php/2009/08/xval-with-webforms-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>xVal with WebForms</title>
		<link>http://www.jrummell.com/blog/index.php/2009/07/xval-with-webforms/</link>
		<comments>http://www.jrummell.com/blog/index.php/2009/07/xval-with-webforms/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 02:32:00 +0000</pubDate>
		<dc:creator>jrummell</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[validation]]></category>
		<category><![CDATA[xval-webforms]]></category>

		<guid isPermaLink="false">/john/blog/post/xVal-with-WebForms.aspx</guid>
		<description><![CDATA[Update: See xVal with WebForms Part 2 for a better implementation. What is xVal and why would anyone want to use it? xVal is a validation framework for ASP.NET MVC applications. It makes it easy to link up your choice of server-side validation mechanism with your choice of client-side validation library, neatly fitting both into [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p><strong>Update</strong>: See <a href="http://john.rummell.info/john/blog/post/xVal-with-WebForms-Part-2.aspx">xVal with WebForms Part 2</a> for a better implementation.</p>
<h2>What is xVal and why would anyone want to use it?</h2>
<blockquote><p>xVal is a validation framework for ASP.NET MVC applications. It makes it easy to link up your choice of server-side validation mechanism with your choice of client-side validation library, neatly fitting both into ASP.NET MVC architecture and conventions.</p></blockquote>
<p><img src="http://blog.codeville.net/wp-content/uploads/2009/01/image-thumb.png" alt="" /></p>
<p>See the <a href="http://xval.codeplex.com/" target="_blank">CodePlex</a> page for more information.</p>
<p>Basically, what xVal does, is take your validation rules and perform server and client side validation based on those rules. That means you don’t have to duplicate model validation at the page level. Now you’re probably thinking, “Isn’t it for MVC?”.  It is. But I, and at least <a href="http://xval.codeplex.com/Thread/View.aspx?ThreadId=60906" target="_blank">two others</a>, would like to take advantage of xVal’s features in traditional ASP.NET WebForm projects.</p>
<h2>Getting it to work with WebForms</h2>
<p>I finally found some time last night to see what it would take to get xVal working in an ASP.NET Web Application Project.  After a few hours I had something. I only needed to add two classes on top of xVal, DataAnnotationsValidationRunner and ModelValidator.</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">class</span> DataAnnotationsValidationRunner
{
    <span class="kwrd">public</span> <span class="kwrd">static</span> IEnumerable&lt;ErrorInfo&gt; GetErrors(<span class="kwrd">object</span> instance, <span class="kwrd">string</span> propertyName)
    {
        <span class="kwrd">return</span> from prop <span class="kwrd">in</span> TypeDescriptor.GetProperties(instance).Cast&lt;PropertyDescriptor&gt;()
               from attribute <span class="kwrd">in</span> prop.Attributes.OfType&lt;ValidationAttribute&gt;()
               <span class="kwrd">where</span> prop.Name == propertyName &amp;&amp; !attribute.IsValid(prop.GetValue(instance))
               select <span class="kwrd">new</span> ErrorInfo(prop.Name, attribute.FormatErrorMessage(<span class="kwrd">string</span>.Empty), instance);
    }
}</pre>
<p>This is based on the implementation in the <a href="http://blog.codeville.net/2009/01/10/xval-a-validation-framework-for-aspnet-mvc/" target="_blank">xVal demo</a>. I added a second parameter to GetErrors() that allows the runner to check a specific property.</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> ModelValidator : BaseValidator
{
    <span class="kwrd">private</span> ValidationInfo _validationInfo;

    <span class="kwrd">public</span> <span class="kwrd">string</span> ModelType
    {
        get { <span class="kwrd">return</span> (<span class="kwrd">string</span>) ViewState[<span class="str">"ModelType"</span>]; }
        set { ViewState[<span class="str">"ModelType"</span>] = <span class="kwrd">value</span>; }
    }

    <span class="kwrd">public</span> <span class="kwrd">string</span> ModelProperty
    {
        get { <span class="kwrd">return</span> (<span class="kwrd">string</span>) ViewState[<span class="str">"ModelProperty"</span>]; }
        set { ViewState[<span class="str">"ModelProperty"</span>] = <span class="kwrd">value</span>; }
    }

    <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">bool</span> EvaluateIsValid()
    {
        Type type = Type.GetType(ModelType);

        <span class="kwrd">object</span> model = Activator.CreateInstance(type);

        IEnumerable&lt;ErrorInfo&gt; errors = DataAnnotationsValidationRunner.GetErrors(model, ModelProperty);

        StringBuilder errorBuilder = <span class="kwrd">new</span> StringBuilder();
        <span class="kwrd">foreach</span> (ErrorInfo error <span class="kwrd">in</span> errors)
        {
            errorBuilder.AppendLine(error.ErrorMessage);
        }

        ErrorMessage = errorBuilder.ToString();

        <span class="kwrd">return</span> ErrorMessage.Length &gt; 0;
    }

    <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Render(HtmlTextWriter writer)
    {
        Type type = Type.GetType(ModelType);
        _validationInfo = <span class="kwrd">new</span> ValidationInfo(ActiveRuleProviders.GetRulesForType(type), String.Empty);

        writer.Write(_validationInfo.ToString());
    }
}</pre>
<p>This is the ASP.NET WebForms version of &lt;%= Html.ClientSideValidation&lt;Booking&gt;(&#8220;booking&#8221;) %&gt;, an implementation of <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.basevalidator.aspx" target="_blank">BaseValidator</a>. It uses <a href="http://xval.codeplex.com/sourcecontrol/changeset/view/21650?projectName=xval#260910" target="_blank">ValidationInfo</a> for rendering the client validation script and DataAnnotationsValidationRunner for the server side validation.</p>
<p>You can use it like this:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Customer
{
    [Required, StringLength(20)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> Name { get; set; }
}</pre>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">script</span> <span class="attr">type</span><span class="kwrd">="text/javascript"</span> <span class="attr">src</span><span class="kwrd">="xVal.AspNetNative.js"</span><span class="kwrd">&gt;&lt;/</span><span class="html">script</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">div</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">asp:Label</span> <span class="attr">ID</span><span class="kwrd">="lblName"</span> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="attr">AssociatedControlID</span><span class="kwrd">="Name"</span><span class="kwrd">&gt;</span>Customer Name:<span class="kwrd">&lt;/</span><span class="html">asp:Label</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">="Name"</span> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">val:ModelValidator</span> <span class="attr">ID</span><span class="kwrd">="validator"</span> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="attr">ModelType</span><span class="kwrd">="xVal.WebForms.Test.Customer, xVal.WebForms.Test"</span>
        <span class="attr">ModelProperty</span><span class="kwrd">="Name"</span> <span class="attr">ControlToValidate</span><span class="kwrd">="Name"</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">asp:Button</span> <span class="attr">ID</span><span class="kwrd">="btnSubmit"</span> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="attr">Text</span><span class="kwrd">="Submit"</span> <span class="kwrd">/&gt;</span></pre>
<p>There are a few things to note here:</p>
<ul>
<li>The TextBox ID must be the same as the model’s property name. This is because the xVal javascript is expecting the control’s ID to be PropertyName or prefix.PropertyName (MVC naming conventions). This could probably be fixed by modifying the <a href="http://xval.codeplex.com/sourcecontrol/changeset/view/21650?projectName=xval#279841" target="_blank">client</a> <a href="http://xval.codeplex.com/sourcecontrol/changeset/view/21650?projectName=xval#279846" target="_blank">side</a> plugins.</li>
<li>The ControlToValidate property on ModelValidator doesn’t do anything, but it’s required by any implementation of BaseValidator (it will throw an exception if you omit it). This could probably be avoided by having ModelValidator inherit from <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.aspx" target="_blank">Control</a> and implement <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.ivalidator.aspx" target="_blank">IValidator</a> instead.</li>
<li>xVal depends on System.Web.Mvc. It uses the TagBuilder and ModelState classes in a <a href="http://xval.codeplex.com/sourcecontrol/changeset/view/21650?projectName=xval#260910" target="_blank">few</a> <a href="http://xval.codeplex.com/sourcecontrol/changeset/view/21650?projectName=xval#72733" target="_blank">places</a>. There’s really now way around this without refactoring the MVC specific stuff into a separate assembly.</li>
</ul>
<p>I’ll post an update when I have a chance to work on the first two items.</p>
<div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:cae34c0a-e527-43b6-873e-c25784f5fccd" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<div class="attachments"><dl class="attachments attachments-large"><dt class="icon"><a title="xVal.WebForms" href="http://www.jrummell.com/blog/index.php/2009/07/xval-with-webforms/?aid=75&amp;sa=0" ><img src="http://www.jrummell.com/blog/wp-content/plugins/eg-attachments/img/flags/zip.png" width="48" height="48" alt="xVal.WebForms" /></a></dt><dd class="caption"><strong>Title</strong> : <a title="xVal.WebForms" href="http://www.jrummell.com/blog/index.php/2009/07/xval-with-webforms/?aid=75&amp;sa=0" >xVal.WebForms</a><br /><strong>Caption</strong> : <br /><strong>File name</strong> : xVal.WebForms.zip<br /><strong>Size</strong> : 268 kB</dd></dl></div>
</div>
<div class="shr-publisher-16"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jrummell.com/blog/index.php/2009/07/xval-with-webforms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

