<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.aspnetzone.de/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Roberto's Blog : Validation</title><link>http://www.aspnetzone.de/blogs/robertobez/archive/tags/Validation/default.aspx</link><description>Ordnungsbegriffe: Validation</description><dc:language /><generator>CommunityServer 2.1 SP2 (Build: 61120.2)</generator><item><title>ASP.NET Mvc 3 unobtrusive validation - erweitern mit eigenen jQuery Adaptern und Validatoren</title><link>http://www.aspnetzone.de/blogs/robertobez/archive/2011/01/13/mvc3-unobtrusive-validation-eigene-jquery-adapter-validator-attributes.aspx</link><pubDate>Thu, 13 Jan 2011 07:30:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:220524</guid><dc:creator>Roberto</dc:creator><slash:comments>1</slash:comments><comments>http://www.aspnetzone.de/blogs/robertobez/comments/220524.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/robertobez/commentrss.aspx?PostID=220524</wfw:commentRss><description>&lt;ol style="list-style:none outside none;"&gt;&lt;li&gt;&lt;a title="Teil 1: ASP.NET Mvc3 unobtrusive Validierung" href="http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/26/asp-net-mvc3-unobtrusive-validation.aspx"&gt;Teil 1: ASP.NET Mvc 3 unobtrusive validation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="Teil 2: ASP.NET Mvc3 unobtrusive validation - clientseitige Adapter" href="http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/27/ASP-NET-mvc3-unobtrusive-validation-clientseitige-adapter.aspx"&gt;Teil 2: Unobtrusive validation - Clientseitige Adapter&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="mvc3 unobtrusive validation - erweitern mit eigenen Adaptern, Attributen und Validatoren" href="http://www.aspnetzone.de/blogs/robertobez/archive/2011/01/13/mvc3-unobtrusive-validation-eigene-jquery-adapter-validator-attributes.aspx"&gt;Teil 3: Unobtrusive validation - Eigene Adapter erstellen&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;Grundsätzlich gibt es serverseitig zwei Möglichkeiten die eigenen Attribute für die Validierung zu Gestalten:&lt;br&gt;&lt;br&gt;Implementierung einer Basisklasse wie &lt;a title="RegularExpressionAttribute" target="_blank" href="http://msdn.microsoft.com/de-de/library/system.componentmodel.dataannotations.regularexpressionattribute.aspx"&gt;RegularExpressionAttribute &lt;/a&gt;sowie des Interfaces &lt;a target="_blank" title="IClientValidatable" href="http://msdn.microsoft.com/en-us/library/system.web.mvc.iclientvalidatable%28v=vs.98%29.aspx"&gt;IClientValidatable&lt;/a&gt;&lt;br&gt;Implementierung einer Basisklasse wie &lt;a title="RegularExpressionAttribute" target="_blank" href="http://msdn.microsoft.com/de-de/library/system.componentmodel.dataannotations.regularexpressionattribute.aspx"&gt;RegularExpressionAttribute &lt;/a&gt;und den Einbau eines &lt;a target="_blank" title="DataAnnotaionsModelValidator" href="http://msdn.microsoft.com/de-de/library/system.web.mvc.dataannotationsmodelvalidator.aspx"&gt;DataAnnotationsModelValidator&lt;/a&gt;&lt;br&gt;&lt;br&gt;Im Prinzip hat &lt;a title="jQuery Adapter zur Konvertierung von HTML5 Attributen" href="http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/27/ASP-NET-mvc3-unobtrusive-validation-clientseitige-adapter.aspx"&gt;der letzte Post&lt;/a&gt; gezeigt, dass ein jQuery Adapter die Konvertierung von HTML5 Attributen in die für jQuery kompatiblen Metadaten vornimmt.&lt;br&gt;&lt;br&gt;Diese HTML5 Attribute haben alle die selbe Form: data-val-&amp;lt;xxx&amp;gt;&lt;br&gt;&lt;br&gt;Als Beispiel gibt es bereits vordefinierte Konstellationen wie &lt;u&gt;data-val-regex&lt;/u&gt; und data-&lt;u&gt;val-regex-pattern&lt;/u&gt;.&lt;br&gt;&lt;br&gt;Somit würde der im Hintergrund stehende Adapter nichts anderes machen, als zu überprüfen, ob ein Feld mit dem Attribut data-val-regex gesetzt ist und wenn ja, das dazugehörige pattern auslesen und validieren.&lt;br&gt;&lt;br&gt;Im nachstehenden Beispiel wird ein eigenes, triviales Email Attribut erstellt, um die Umsetzung etwas deutlicher zu erklären.&lt;br&gt;&lt;br&gt;&lt;b&gt;Möglichkeit 1) IClientValidatable&lt;/b&gt;&lt;br&gt;&lt;br&gt;Das Attribut

&lt;pre class="brush: c#;"&gt;public class EmailWithoutValidatorAttribute : RegularExpressionAttribute, IClientValidatable 
{ 
    public EmailWithoutValidatorAttribute() : base(@"&amp;lt;emailregex&amp;gt;")
    {

    }
 
    public IEnumerable&amp;lt;ModelClientValidationRule&amp;gt; GetClientValidationRules(ModelMetadata metadata, 
                                                                             ControllerContext context)
    {
        var rule = new ModelClientValidationRule(...);
        return new[] { rule };
    }
}
&lt;/pre&gt;

Eigentlich nur ein RegularExpressionAttrubite wie von früheren Zeiten gewohnt, sowie eine zusätzliche Methode GetClientValidationRules, die die Rückgabe einer Liste von Regeln erwartet. Ob eine oder mehrere Regeln zurückgegeben werden, ist irrelevant.&lt;br&gt;&lt;br&gt;Nun reicht eine normale &lt;a target="_blank" title="ModelClientValidationRule" href="http://msdn.microsoft.com/en-us/library/system.web.mvc.modelclientvalidationrule.aspx"&gt;ModelClientValidationRule &lt;/a&gt;für das Vorhaben nicht aus, somit wird eine eigene erstellt. Diese hat den Vorteil, dass ein eigener &lt;b&gt;validationType &lt;/b&gt;(Der eigentliche Name des Adapters, der später benötigt wird) angegeben werden kann.

&lt;pre class="brush: c#;"&gt;public class NamedRegexValidationRule : ModelClientValidationRule
{
    public NamedRegexValidationRule(string errorMessage,
                               string pattern, string validationType)
    {
        this.ErrorMessage = errorMessage;
        this.ValidationType = validationType;
        this.ValidationParameters.Add("pattern", pattern);
    }
}
&lt;/pre&gt;

Die im Code gezeigten ValidationParemeters können beliebig gefüllt werden, benötigt wird hier ausschließlich das Pattern.&lt;br&gt;&lt;br&gt;&lt;i&gt;Hinweis: Die &amp;lt;string, object&amp;gt; collection kann beliebig gefüllt werden. Letztendlich&amp;nbsp; wird jedes Element als ein html Attribut data-val-&amp;lt;string&amp;gt;="&amp;lt;value&amp;gt;" gerendert. Es ist somit egal, ob "pattern" oder "blubr" vorkommt.&lt;/i&gt;&lt;br&gt;&lt;br&gt;Die angepasste Methode im Attribut würde somit wie folgt aussehen (Wichtig ist der Name „customemail“, dieser wird als Adaptername verwendet und kann ausschließlich mit Kleinbuchstaben angegeben werden)

&lt;pre class="brush: c#;"&gt;public IEnumerable&amp;lt;ModelClientValidationRule&amp;gt; GetClientValidationRules(ModelMetadata metadata, 
                                                                         ControllerContext context)
{
    var rule = new NamedRegexValidationRule(this.ErrorMessage, this.Pattern, "customemail");
    return new[] { rule };
}
&lt;/pre&gt;

Angenommen es ist ein Model "Person" mit einer Eigenschaft "Email" vorhanden, die mit dem eben erstellen Attribut versehen ist:

&lt;pre class="brush: c#;"&gt;public class Person
{
    [EmailWithoutValidator(ErrorMessage = "Not a valid email.")]
    public string Email { get; set; }
}
&lt;/pre&gt;

Das dazugehörige Feld als gerenderter Version &lt;i&gt;@Html.TextBoxFor(p =&amp;gt; p.Email)&lt;/i&gt;

&lt;pre class="brush: html;"&gt;&amp;lt;input type="text" value="" name="Email" id="Email" class="input-validation-error"
    data-val-customemail-pattern="&amp;lt;EmailPattern&amp;gt;" 
    data-val-customemail="Not a valid email." 
    data-val="true"&amp;gt;
&lt;/pre&gt;

Zwei Sachen wurden damit erreicht:&lt;br&gt;&lt;ul&gt;&lt;li&gt;&lt;u&gt;data-val-customemail&lt;/u&gt; steht für die angegebene Fehlermeldung.&lt;/li&gt;&lt;li&gt;&lt;u&gt;data-val-customemail-pattern&lt;/u&gt; steht für das angegebene Email Pattern.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;b&gt;Möglichkeit 2)&lt;/b&gt; &lt;b&gt;DataAnnotationsModelValidator&lt;/b&gt;

&lt;pre class="brush: c#;"&gt;public class EmailWithValidatorAttribute : RegularExpressionAttribute
{
    public EmailWithValidatorAttribute() : base(@"&amp;lt;EmailRegex&amp;gt;")
    {
    }
}
&lt;/pre&gt;

Nichts anderes als bei Möglichkeit 1, ohne der Implementierung des IClientValidatable Interfaces und somit der Erstellung der Regeln.&lt;br&gt;&lt;br&gt;Diese werden bei dieser Variante &lt;b&gt;in den Validator&lt;/b&gt; ausgelagert:

&lt;pre class="brush: c#;"&gt;public class EmailValidator : DataAnnotationsModelValidator&amp;lt;EmailWithValidatorAttribute&amp;gt;
{
    private readonly string _errorMessage;
    private readonly string _pattern;

    public EmailValidator(ModelMetadata metadata, ControllerContext context, EmailWithValidatorAttribute attribute) 
                       : base(metadata, context, attribute)
    {
        this._errorMessage = attribute.ErrorMessage;
        this._pattern = attribute.Pattern;
    }

    public override IEnumerable&amp;lt;ModelClientValidationRule&amp;gt; GetClientValidationRules()
    {
        var rule = new NamedRegexValidationRule(this._errorMessage, this._pattern, "customemail");
        return new[] { rule };
    }
}
&lt;/pre&gt;

Auch hier gibt es eine Methode &lt;u&gt;GetClientValidationRules()&lt;/u&gt;, die eigentlich die selbe Logik beinhaltet, wie in Möglichkeit 1.&lt;br&gt;&lt;br&gt;Zusätzlich muss der Validator nun in der Global.asax (In der application start Methode) noch mit Angabe des Attributes registriert werden:

&lt;pre class="brush: c#;"&gt;DataAnnotationsModelValidatorProvider.RegisterAdapter(
                            typeof(EmailWithValidatorAttribute), 
                            typeof(EmailValidator));
&lt;/pre&gt;

Im Prinzip bringen beide Möglichkeiten das selbe Ergebnis, Möglichkeit 1 hat den Nachteil (zumindest für den ein oder anderen), dass die Logik direkt im Attribut steht und Möglichkeit 2 lagert dies in einen externen Validator aus. Somit ist das Attribut nicht MVC abhängig und könnte auch für andere Zwecke verwendet werden, bzw. bereits vorhandene Attribute könnten problemlos wiederverwendet werden.&lt;br&gt;&lt;br&gt;&lt;br&gt;Last but not least, &lt;b&gt;der clientseitige Aufbau des Adapters.&lt;/b&gt;&lt;br&gt;&lt;br&gt;Die jQuery unobtrusive validation Bibliothek stellt eine Methode Add() zur Verfügung, über welche neue, eigene Adapter registiert werden können. Diese nimmt als Parameter einmal den Adapternamen, den/die Attributnamen die benötig werden, sowie eine Funktion, über die die eigene Logik implementiert werden kann.&lt;br&gt;

&lt;pre class="brush: js;"&gt;jQuery.validator.unobtrusive.adapters.add("customemail", ["pattern"], function (options) {

    if (options.element.tagName.toUpperCase() == "INPUT") {

        // Set the regex rule with the given pattern.
        options.rules["regex"] = options.params.pattern;

        if (options.message) {
            options.messages["regex"] = options.message;
        }
    }
});
&lt;/pre&gt;

Wie im &lt;a title="jQuery Validation Adapter object parameters" href="http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/27/ASP-NET-mvc3-unobtrusive-validation-clientseitige-adapter.aspx"&gt;letzten Post gezeigt&lt;/a&gt;, beinhaltet das options Objekt Regeln, Parameter und Mitteilungen, über die die Validierung gesteuert wird.&lt;br&gt;&lt;br&gt;In Falle einer Email Validierung reicht eine regex Regel aus, es können aber beliebig viele hinzugefügt werden. Wichtig ist hierbei nur, dass diese als Paremter angegeben werden ["pattern", "&amp;lt;anderes Attribut"&amp;gt;, ...]&lt;br&gt;&lt;br&gt;Natürlich macht es nicht wirklich viel Sinn, ein Email Attribut so kompliziert zu gestalten, viel mehr geht es darum zu zeigen, wie es im Verhältnis doch einfach ist, eigene Adapter zu erstellen. Im Web 2.0 Zeitalter ist eine kombination aus client und server Validierung eher Standard als eine Ausnahme. Mit ein bisschen Mühe können tolle Sachen, wie bspw.&amp;nbsp; eine Überprüfung, ob ein Username einzigartig ist entwickelt werden. Der Große Vorteil liegt auch hier in der Entkoppelung der Validierungslogik vom restlichen Teil der Anwendung.&lt;br&gt;&lt;br&gt;Anbei gibt’s wie immer das Beispiel zum Post.&lt;br&gt;&lt;br&gt;&lt;div class="DownloadBox"&gt;
&lt;a title="ASP.NET MVC 3 custom unobstrusive validation sample with jQuery adapters, attributes and validators" href="http://www.aspnetzone.de/files/folders/220527/download.aspx"&gt;ASP.NET MVC 3 unobstrusive custom validation sample.&lt;/a&gt;&lt;br&gt;
&lt;/div&gt;
&lt;a href="http://dotnet-kicks.de/kick/?url=http://www.aspnetzone.de/blogs/robertobez/archive/2011/01/13/mvc3-unobtrusive-validation-eigene-jquery-adapter-validator-attributes.aspx"&gt;&lt;img src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=http://www.aspnetzone.de/blogs/robertobez/archive/2011/01/13/mvc3-unobtrusive-validation-eigene-jquery-adapter-validator-attributes.aspx&amp;amp;bgcolor=3169AD&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks-DE Image" border="0"&gt;&lt;/a&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=220524" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Asp.Net/default.aspx">Asp.Net</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Mvc/default.aspx">Mvc</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Validation/default.aspx">Validation</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Html5/default.aspx">Html5</category></item><item><title>ASP.NET unobtrusive validation - Clientseitige Adapter</title><link>http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/27/ASP-NET-mvc3-unobtrusive-validation-clientseitige-adapter.aspx</link><pubDate>Mon, 27 Dec 2010 13:15:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:220384</guid><dc:creator>Roberto</dc:creator><slash:comments>2</slash:comments><comments>http://www.aspnetzone.de/blogs/robertobez/comments/220384.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/robertobez/commentrss.aspx?PostID=220384</wfw:commentRss><description>&lt;ol style="list-style:none outside none;"&gt;&lt;li&gt;&lt;a title="Teil 1: ASP.NET Mvc3 unobtrusive Validierung" href="http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/26/asp-net-mvc3-unobtrusive-validation.aspx"&gt;Teil 1: ASP.NET Mvc 3 unobtrusive validation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="Teil 2: ASP.NET Mvc3 unobtrusive validation - clientseitige Adapter" href="http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/27/ASP-NET-mvc3-unobtrusive-validation-clientseitige-adapter.aspx"&gt;Teil 2: Unobtrusive validation - Clientseitige Adapter&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="mvc3 unobtrusive validation - erweitern mit eigenen Adaptern, Attributen und Validatoren" href="http://www.aspnetzone.de/blogs/robertobez/archive/2011/01/13/mvc3-unobtrusive-validation-eigene-jquery-adapter-validator-attributes.aspx"&gt;Teil 3: Unobtrusive validation - Eigene Adapter erstellen&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;Wie bereits &lt;a title="Teil 1: ASP.NET Mvc3 unobtrusive Validierung" href="http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/26/asp-net-mvc3-unobtrusive-validation.aspx"&gt;im letzten Post&lt;/a&gt; beschrieben, gibt es seit der dritten Version des MVC Frameworks die Möglichkeit, Formular Validierungen über HTML 5 kompatible Attribute zu machen.&lt;br&gt;&lt;br&gt;Diese werden clientseitig über &lt;a title="Adapter" target="_blank" href="http://de.wikipedia.org/wiki/Adapter_%28Entwurfsmuster%29"&gt;Adapter&lt;/a&gt; umgesetzt, die die entsprechenden Parameterwerte aus den HTML 5 Attributen in die für jQuery Validate vorgesehenen Metadaten konvertieren.&lt;br&gt;&lt;br&gt;In diesem Post wird nicht genauer auf das jQuery Validate Plugin eingegangen, sondern mehr über die Logik und Konvertierungsmechanismen der Adapter.&lt;br&gt;&lt;br&gt;Mehr Informationen zu jQuery Validate finden sich &lt;a title="jQuery Validate Plugin" target="_blank" href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/"&gt;hier&lt;/a&gt;.&lt;br&gt;&lt;br&gt;Als weiteres, für den Post relevanteres Plugin findet sich das &lt;i&gt;jQuery.validator.unobtrusive.adapters.js&lt;/i&gt; im Ordner Scripts eines jeden MVC3 Projekttemplates.&lt;br&gt;&lt;br&gt;Im Script gibt es eine Registrierungsmethode "add", sowie einige allgemeine Methoden "addBool", "addSingleVal" und "addMinMax".&lt;br&gt;&lt;br&gt;Im Grunde sind die meisten Fälle damit abgedeckt, als Beispiel ein Auszug aus der eben genannten Datei:&lt;br&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;adapters.addBool(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"creditcard"&lt;/span&gt;).addBool(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"date"&lt;/span&gt;).addBool(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"digits"&lt;/span&gt;).addBool(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"email"&lt;/span&gt;).addBool(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"number"&lt;/span&gt;).addBool(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"url"&lt;/span&gt;);&lt;br /&gt;adapters.addSingleVal(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"accept"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"exts"&lt;/span&gt;).addSingleVal(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"regex"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"pattern"&lt;/span&gt;);&lt;br /&gt;adapters.addMinMax(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"length"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"minlength"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"maxlength"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"rangelength"&lt;/span&gt;).addMinMax(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"range"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"min"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"max"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"range"&lt;/span&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;br&gt;Bevor genauer auf die einzelnen Methoden eingegangen wird, eine kurze Erklärung zur Methode "add", die intern von jeder aufgerufen wird:&lt;br&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;adapters.add &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;function&lt;/span&gt; (adapterName, params, fn)&lt;br /&gt;{&lt;br /&gt;....&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;adapterName&lt;/b&gt;: Ist der Name des zu hinzuzufügenden Adapters. Im Prinzip nichts anderes, als der im Attribut data-val-&amp;lt;Name&amp;gt; vorkommenden Platzhalter.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;params&lt;/b&gt;: Ist ein optionales Array aus Parametern, die aus den Attributen data-val-&amp;lt;Name&amp;gt;-&amp;lt;Paremter&amp;gt; extrahiert werden.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;fn&lt;/b&gt;: Ist die Funktion, welche die Werte der Html Attribute in die für "jQuery Validate" benötigten Regeln und/oder Mitteilungen konvertiert.&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;Die Methode &lt;b&gt;addBool&lt;/b&gt; macht somit einen in etwa ähnlichen Aufruf: &lt;br&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;add(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"email"&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;function&lt;/span&gt;(options) {&lt;br /&gt;    ...&lt;br /&gt;    options.rules[&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"required"&lt;/span&gt;] &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; true;&lt;br /&gt;    ...&lt;br /&gt;});&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Hinweis&lt;/i&gt;: Das &lt;b&gt;option Element&lt;/b&gt; beinhaltet &lt;b&gt;folgende Werte:&lt;/b&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;element&lt;/b&gt;: Das HTML Element dem der Validator zugeordnet ist.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;form&lt;/b&gt;: Das HTML Form Element.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;message&lt;/b&gt;: Die Ausgabe, die ebenfalls aus den HTML Attributen extrahiert wird.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;params&lt;/b&gt;: Ein Array Element mit Werten, die aus den HTML Attributen extrahiert werden. (Bspw. var min = options.params.min)&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;rules&lt;/b&gt;: Das Array Element, das die Namen und Werte beinhaltet, die wiederum für die jQuery Validate Regel benötigt werden. (Bspw. ["required"] = true)&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;messages&lt;/b&gt;: Ein Array Element, das die Namen und Werte beinhaltet, wobei der Name für die verletze Regel und der Wert für die dazugehörige Ausgabe stehen. (Bspw. ["required"] = "Das Feld darf nicht leer sein.")&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;Nun sollte auch die &lt;b&gt;addSingleValue&lt;/b&gt; anhand eines Beispiels verständlich werden:&lt;br&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;adapters.addSingleVal(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"regex"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"pattern"&lt;/span&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;br&gt;Gegeben ist ein HTML Element, wobei die Eingabe nicht leer sein kann und es nur Großbuchstaben beinhalten darf. (= dem Regex [A-Z] enstprechen).&lt;br&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;input ... &lt;br /&gt;data-val="true"&lt;br /&gt;data-val-required="Das Feld darf nicht leer sein."&lt;br /&gt;data-val-regex="Das Feld darf nur Großbuchstaben beinhalten."&lt;br /&gt;data-val-regex-pattern="[A-Z]" /&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;br&gt;Folgende Werte würden daraus entstehen:&lt;br&gt;&lt;br&gt;-&amp;gt; options.rules["required"] = true&lt;br&gt;-&amp;gt; options.rules["regex"] = "[A-Z]"&lt;br&gt;-&amp;gt; options.messages["required"] = "Das Feld darf nicht leer sein."&lt;br&gt;
-&amp;gt; options.messages["regex"] = "Das Feld darf nur Großbuchstaben beinhalten."&lt;br&gt;&lt;br&gt;Und natürlich würde auch addMinMax nichts anderes machen, als ein paar "rules" wie bspw. "min", "max" zu setzen.&lt;br&gt;&lt;br&gt;Am Besten einfach ein paar Testelemente machen und mit der &lt;a title="Firebug - Firefox Extensions" target="_blank" href="https://addons.mozilla.org/de/firefox/addon/1843/"&gt;Firefox Extension Firebug&lt;/a&gt; ansehen.&lt;br&gt;&lt;br&gt;Im nächsten Teil wird dann genauer auf die Erstellung eigener Adapters eingegangen!&lt;br&gt;&lt;br&gt;

&lt;a href="http://dotnet-kicks.de/kick/?url=http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/27/ASP-NET-mvc3-unobtrusive-validation-clientseitige-adapter.aspx"&gt;&lt;img src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/27/ASP-NET-mvc3-unobtrusive-validation-clientseitige-adapter.aspx&amp;amp;bgcolor=3169AD&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks-DE Image" border="0"&gt;&lt;/a&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=220384" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Asp.Net/default.aspx">Asp.Net</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Mvc/default.aspx">Mvc</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Validation/default.aspx">Validation</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Html5/default.aspx">Html5</category></item><item><title>ASP.NET Mvc 3 unobtrusive validation</title><link>http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/26/asp-net-mvc3-unobtrusive-validation.aspx</link><pubDate>Sun, 26 Dec 2010 10:55:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:220382</guid><dc:creator>Roberto</dc:creator><slash:comments>1</slash:comments><comments>http://www.aspnetzone.de/blogs/robertobez/comments/220382.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/robertobez/commentrss.aspx?PostID=220382</wfw:commentRss><description>&lt;img src="http://11249.2.sihosting.net/Blog/Images/MvcValidation.png" style="float:left;margin-right:10px;" alt="ASP.NET MVC3 unobtrusive Validation"&gt;In dieser dreiteiligen Postreihe wird gezeigt, wie sich ab ASP.NET Mvc 3 die Validierung von Formularen geändert hat, welche Vorteile sie mit sich bringt und wie die Validierung mit eigenen Regeln erweitert wird.&lt;br&gt;&lt;div style="margin-left:10px;"&gt;&lt;ol style="list-style:none outside none;"&gt;&lt;li&gt;&lt;a title="Teil 1: ASP.NET Mvc3 unobtrusive Validierung" href="http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/26/asp-net-mvc3-unobtrusive-validation.aspx"&gt;Teil 1: ASP.NET Mvc 3 unobtrusive validation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="Teil 2: ASP.NET Mvc3 unobtrusive validation - clientseitige Adapter" href="http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/27/ASP-NET-mvc3-unobtrusive-validation-clientseitige-adapter.aspx"&gt;Teil 2: Unobtrusive validation - Clientseitige Adapter&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="mvc3 unobtrusive validation - erweitern mit eigenen Adaptern, Attributen und Validatoren" href="http://www.aspnetzone.de/blogs/robertobez/archive/2011/01/13/mvc3-unobtrusive-validation-eigene-jquery-adapter-validator-attributes.aspx"&gt;Teil 3: Unobtrusive validation - Eigene Adapter erstellen&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br style="clear:left;"&gt;Bereits in &lt;a target="_blank" title="ASP.NET MVC2" href="http://www.asp.net/mvc"&gt;MVC2&lt;/a&gt; gab es eine client und serverseitige &lt;a target="_blank" title="MVC2 model validation" href="http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx"&gt;Validierung für Models&lt;/a&gt;.&lt;br&gt;Standartmäßig für den Client mit ASP.NET Ajax, aber auch mit einer kleinen &lt;a target="_blank" title="JQuery" href="http://www.jquery.com"&gt;jQuery &lt;/a&gt;Erweiterung machbar.&lt;br&gt;&lt;br&gt;Bereits durch dieses Verfahren wurde der &lt;b&gt;serverseitige Teil&lt;/b&gt; (Durch den Einsatz von DataAnnotations) vom &lt;b&gt;Clientseitigen &lt;/b&gt;entkoppelt.&lt;br&gt;&lt;br&gt;&lt;br style="clear:left;"&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; Mandant&lt;br /&gt;{&lt;br /&gt;    [Required(ErrorMessage &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Name is required."&lt;/span&gt;)]&lt;br /&gt;    [StringLength(50, ErrorMessage &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Must be under 50 characters."&lt;/span&gt;)]&lt;br /&gt;    [DisplayName(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Mandant Name"&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; Name { get; set; }&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;br&gt;Was im Html Code dabei gerendert wird, sieht in etwa so aus:&lt;span class="sourceRowText "&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;//&amp;lt;![CDATA[&lt;br /&gt;if (!window.mvcClientValidationMetadata) { window.mvcClientValidationMetadata = []; }&lt;br /&gt;window.mvcClientValidationMetadata.push({"Fields":[{"FieldName":"Mandant.Name","ReplaceValidationMessageContents":true,"ValidationMessageId":"Mandant_Name_validationMessage","ValidationRules":[{"ErrorMessage":"Name is required.","ValidationParameters":{},"ValidationType":"required"},{"ErrorMessage":"Must be under 50 characters.","ValidationParameters":{"minimumLength":0,"maximumLength":50},"ValidationType":"stringLength"}]}, ...&lt;br /&gt;//]]&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;br&gt;Ab der dritten Version des MVC Frameworks wird die Validierung hingegen etwas schicker gelöst.&lt;br&gt;&lt;br&gt;Im Prinzip bringt die Neuerung den Vorteil mit sich, dass auf einen langen JSON String im Html code &lt;b&gt;verzichtet wird&lt;/b&gt; und dafür auf &lt;b&gt;HTML5 kompatible Attribute&lt;/b&gt; gesetzt wird, die die Validierung der Input Felder beschreiben.&lt;br&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;input&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;type&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="text"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;value&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=""&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;name&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="Name"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;id&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="Name"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;data-val-required&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="The Name field is required."&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;data-val&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="true"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="input-validation-error"&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;input&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;type&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="text"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;value&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=""&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;name&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="Age"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;id&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="Age"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;data-val-required&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="The Age field is required."&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;data-val-number&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="The field Age must be a number."&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;data-val&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="true"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="input-validation-error"&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;br&gt;Ein weiterer Vorteil ist der Verzicht auf automatisch generierte IDs, da die Informationen nun direkt am Input Feld angefügt werden.&lt;br&gt;&lt;br&gt;Um diese "&lt;b&gt;unobtrusive&lt;/b&gt;" (Übersetzt: unauffällig, bescheiden) Validierung nutzen zu können, sind zwei einfache Schritte notwendig.&lt;br&gt;&lt;br&gt;Folgende Script Bilbiotheken einbinden:&lt;br&gt;&lt;br&gt;&lt;i&gt;(Beim erstellen eines neuen MVC3 Projekts werden diese standartmäßig eingebunden)&lt;/i&gt;&lt;br&gt;&lt;span style="color:blue;"&gt;&lt;br&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&amp;nbsp;&lt;span style="color:red;"&gt;src&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:blue;"&gt;"&lt;/span&gt;&lt;span style="background:none repeat scroll 0% 0% yellow;"&gt;@&lt;/span&gt;&lt;span style="color:blue;"&gt;Url&lt;/span&gt;&lt;span style="color:blue;"&gt;.&lt;/span&gt;&lt;span style="color:blue;"&gt;Content&lt;/span&gt;&lt;span style="color:blue;"&gt;(&lt;/span&gt;&lt;span&gt;"~/Scripts/jquery-1.4.1.min.js"&lt;/span&gt;&lt;span style="color:blue;"&gt;)"&lt;/span&gt;&amp;nbsp;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:blue;"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&amp;nbsp;&lt;span style="color:red;"&gt;src&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:blue;"&gt;"&lt;/span&gt;&lt;span style="background:none repeat scroll 0% 0% yellow;"&gt;@&lt;/span&gt;&lt;span style="color:blue;"&gt;Url&lt;/span&gt;&lt;span style="color:blue;"&gt;.&lt;/span&gt;&lt;span style="color:blue;"&gt;Content&lt;/span&gt;&lt;span style="color:blue;"&gt;(&lt;/span&gt;&lt;span&gt;"~/Scripts/jquery.unobtrusive-ajax.min.js"&lt;/span&gt;&lt;span style="color:blue;"&gt;)"&lt;/span&gt;&amp;nbsp;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:blue;"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&amp;nbsp;&lt;span style="color:red;"&gt;src&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:blue;"&gt;"&lt;/span&gt;&lt;span style="background:none repeat scroll 0% 0% yellow;"&gt;@&lt;/span&gt;&lt;span style="color:blue;"&gt;Url&lt;/span&gt;&lt;span style="color:blue;"&gt;.&lt;/span&gt;&lt;span style="color:blue;"&gt;Content&lt;/span&gt;&lt;span style="color:blue;"&gt;(&lt;/span&gt;&lt;span&gt;"~/Scripts/jquery.validate.min.js"&lt;/span&gt;&lt;span style="color:blue;"&gt;)"&lt;/span&gt;&amp;nbsp;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:blue;"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&amp;nbsp;&lt;span style="color:red;"&gt;src&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:blue;"&gt;"&lt;/span&gt;&lt;span style="background:none repeat scroll 0% 0% yellow;"&gt;@&lt;/span&gt;&lt;span style="color:blue;"&gt;Url&lt;/span&gt;&lt;span style="color:blue;"&gt;.&lt;/span&gt;&lt;span style="color:blue;"&gt;Content&lt;/span&gt;&lt;span style="color:blue;"&gt;(&lt;/span&gt;&lt;span&gt;"~/Scripts/jquery.validate.unobtrusive.min.js"&lt;/span&gt;&lt;span style="color:blue;"&gt;)"&lt;/span&gt;&amp;nbsp;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:blue;"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;Dazu noch sicherstellen, dass in der Web.Config folgende Einstellungen gesetzt sind:&lt;br&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;appSettings&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;add&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;key&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="ClientValidationEnabled"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;value&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="true"&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;/&amp;gt;&lt;/span&gt; &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;add&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;key&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="UnobtrusiveJavaScriptEnabled"&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;value&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="true"&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;appSettings&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;i&gt;&lt;br&gt;Diese sind ebenfalls ab einem MVC3 Projekt-Template standartmäßig dabei, bei einem Upgrade von einer älteren Version müssen sie manuell hinzugefügt werden.&lt;br&gt;&lt;/i&gt;&lt;br&gt;Die eben genannten Einstellungen sind Global für das ganze Projekt, natürlich gibts diese auch Kontext spezifisch:&lt;br&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;HtmlHelper.ClientValidationEnabled &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;true&lt;/span&gt;;&lt;br /&gt;HtmlHelper.UnobtrusiveJavaScriptEnabled &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;true&lt;/span&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;br&gt;Dazu wie gewohnt das Model mit den DataAnnotations versehen (siehe weiter oben) und das Ganze sollte funktionieren.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Und wie das Ganze im Hintergrund funktioniert?&lt;/b&gt;&lt;br&gt;&lt;br&gt;Grundsätzlich hängt alles davon ab, ob das &lt;b&gt;data-val="true"&lt;/b&gt; Attribut gesetzt ist.&lt;br&gt;Dieses wird dem Feld hinzugefügt, wenn mindestens eine Regel aktiv ist. &lt;br&gt;Die wohl am meisten verwendete Regel ist jene, die besagt, ob ein Feld ein Pflichtfeld ist. (Html Attribut dazu: data-val-required="true")&lt;br&gt;Natürlich gibt es zusätzlich verschiedene optionale &lt;a target="_blank" title="Data Annotations" href="http://msdn.microsoft.com/de-de/library/system.componentmodel.dataannotations.aspx"&gt;Attribute &lt;/a&gt;wie data-val-length, data-val-length-min (max), data-val-range-min (max), data-val-regex, data-val-regex-pattern, usw.&lt;br&gt;&lt;br&gt;&lt;b&gt;&lt;br&gt;Fazit:&lt;/b&gt;&lt;br&gt;&lt;br&gt;Ich habe bereits ein Projekt umgestellt, es geht relativ fix und ist doch um einiges schöner - somit: man sollte sich die Arbeit antun.&lt;br&gt;&lt;br&gt;Im nächsten Post wird genauer auf eigene jQuery Validators eingegangen, schaut also vorbei :-)&lt;br&gt;&lt;br&gt;Anbei wie immer das Beispiel:&lt;br&gt;&lt;br&gt;

&lt;div class="DownloadBox"&gt;
&lt;a title="ASP.NET MVC 3 unobstrusive validation sample" href="http://www.aspnetzone.de/files/folders/220381/download.aspx"&gt;ASP.NET MVC 3 unobstrusive validation sample.&lt;/a&gt;
&lt;/div&gt;
&lt;a href="http://dotnet-kicks.de/kick/?url=http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/26/asp-net-mvc3-unobtrusive-validation.aspx"&gt;&lt;img src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=http://www.aspnetzone.de/blogs/robertobez/archive/2010/12/26/asp-net-mvc3-unobtrusive-validation.aspx&amp;amp;bgcolor=3169AD&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks-DE Image" border="0"&gt;&lt;/a&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=220382" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Asp.Net/default.aspx">Asp.Net</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Mvc/default.aspx">Mvc</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Validation/default.aspx">Validation</category><category domain="http://www.aspnetzone.de/blogs/robertobez/archive/tags/Html5/default.aspx">Html5</category></item></channel></rss>