Asp.net MVC source code analysis-Model Validation (Client) implementation (1)

Source: Internet
Author: User

First two: http://www.bkjia.com/kf/201112/115715.html
Http://www.bkjia.com/kf/201112/115716.html

The first two articles introduce the implementation of ModelValidatoin Server. if we set ClientValidationEnabled to true in config, the client can also support form verification. what if this function is implemented? Today, let's take a look at the implementation of the Model validation client.
I. ModelClientValidationRule class
This class defines how to output some client information:
• ErrorMessage: gets or sets an error message for user-side verification rules.
• ValidationParameters: gets a list of verification parameters.
• ValidationType: gets or sets the verification type.
1 public class ModelClientValidationRule {
2
3 private readonly Dictionary <string, object> _ validationParameters = new Dictionary <string, object> ();
4 private string _ validationType;
5
6 public string ErrorMessage {
7 get;
8 set;
9}
10
11 public IDictionary <string, object> ValidationParameters {
12 get {
13 return _ validationParameters;
14}
15}
16
17 public string ValidationType {
18 get {
19 return _ validationType ?? String. Empty;
20}
21 set {
22 _ validationType = value;
23}
24}
25}
Copy code
We know the data structure of this class. How is the data output? Let's take a look at the RequiredAttributeAdapter class. Here we define a GetClientValidationRules method. This method returns the ModelClientValidationRequiredRule object (including the data that Required validation needs to output to the client ).
1 public class RequiredAttributeAdapter: DataAnnotationsModelValidator <RequiredAttribute> {
2 public RequiredAttributeAdapter (ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
3: base (metadata, context, attribute ){
4}
5
6 public override IEnumerable <ModelClientValidationRule> GetClientValidationRules (){
7 return new [] {new ModelClientValidationRequiredRule (ErrorMessage )};
8}
9}
Copy code
2. If you want to get the custom Client Validaton information?
The above describes some system-built (Required) Validation outputs. What if we need custom Validation rules to output client data? We have introduced the custom verification in the DataAnnotationsModelValidatorProvider. GetValidators method, which is constructed through the DefaultAttributeFactory delegate. Let's continue with this code.
1 internal static DataAnnotationsModelValidationFactory defaultbutefactory =
2 (metadata, context, attribute) => new DataAnnotationsModelValidator (metadata, context, attribute );
Copy code
Let me take a look at the implementation of the DataAnnotationsModelValidator. GetClientValidationRules method. We can see the following code line 4th, indicating that only the custom validationatriable interface can output client data.
1 public override IEnumerable <ModelClientValidationRule> GetClientValidationRules (){
2 IEnumerable <ModelClientValidationRule> results = base. GetClientValidationRules ();
3
4 IClientValidatable clientValidatable = Attribute as IClientValidatable;
5 if (clientValidatable! = Null ){
6 results = results. Concat (clientValidatable. GetClientValidationRules (Metadata, ControllerContext ));
7}
8
9 return results;
10}
Copy code
3. If the User-Defined Client Validaton information is output to the browser?
The above analysis shows that we have obtained the Cient validation data. How can we output the data to the browser?
Generally, the code on the View page is as follows:
1 <div class = "editor-label">
2 Name
3 </div>
4 <div class = "editor-field">
5 @ Html. TextBoxFor (m => m. UserName)
6 @ Html. ValidationMessageFor (m => m. UserName)
7 </div>
Copy code
That is to say, the Client Validaton information is output through the Html. TextBoxFor method, so let's study how this method is implemented.
In the InputExtension. cs component's InputHelper method, we found some code snippets related to Client Validaton. The GetUnobtrusiveValidationAttributes method of the following 9th lines of code implements the output.
1 // If there are any errors for a named field, we add the css attribute.
2 ModelState modelState;
3 if (htmlHelper. ViewData. ModelState. TryGetValue (fullName, out modelState )){
4 if (modelState. Errors. Count> 0 ){
5 tagBuilder. AddCssClass (HtmlHelper. ValidationInputCssClassName );
6}
7}
8
9 tagBuilder. MergeAttributes (htmlHelper. GetUnobtrusiveValidationAttributes (name, metadata ));
Copy code
Source code of the GetUnobtrusiveValidationAttributes method:
1 // Only render attributes if unobtrusive client-side validation is enabled, and then only if we 've
2 // never rendered validation for a field with this name in this form. Also, if there's no form context,
3 // then we can't render the attributes (we 'd have no <form> to attach them ).
4 public IDictionary <string, object> GetUnobtrusiveValidationAttributes (string name, ModelMetadata metadata ){
5 Dictionary <string, object> results = new Dictionary <string, object> ();
6
7 // The ordering of these 3 checks (and the early exits) is for performance reasons.
8 if (! ViewContext. UnobtrusiveJavaScriptEnabled ){
9 return results;
10}
11
12 FormContext formContext = ViewContext. GetFormContextForClientValidation ();
13 if (formContext = null ){
14 return results;
15}
16
17 string fullName = ViewData. TemplateInfo. GetFullHtmlFieldName (name );
18 if (formContext. RenderedField (fullName )){
19 return results;
20}
21
22 formContext. RenderedField (fullName, true );
23
24 IEnumerable <ModelClientValidationRule> clientRules = ClientValidationRuleFactory (name, metadata );
25 bool renderedRules = false;
26
27 foreach (ModelClientValidationRule rule in clientRules ){
28 renderedRules = true;
29 string ruleName = "data-val-" + rule. ValidationType;
30
31 ValidateUnobtrusiveValidationRule (rule, results, ruleName );
32
33 results. Add (ruleName, HttpUtility. HtmlEncode (rule. ErrorMessage ?? String. Empty ));
34 ruleName + = "-";
35
36 foreach (var kvp in rule. ValidationParameters ){
37 results. Add (ruleName + kvp. Key, kvp. Value ?? String. Empty );
38}
39}
40
41 if (renderedRules ){
42 results. Add ("data-val", "true ");
43}
44
45 return results;
46}
Copy code
HtmlHelper constructor source code:
1 public HtmlHelper (ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection ){
2 if (viewContext = null ){
3 throw new ArgumentNullException ("viewContext ");
4}
5 if (viewDataContainer = null ){
6 throw new ArgumentNullException ("viewDataContainer ");
7}
8 if (routeCollection = null ){
9 throw new ArgumentNullException ("routeCollection ");
10} www.2cto.com
11
12 ViewContext = viewContext;
13 ViewDataContainer = viewDataContainer;
14 RouteCollection = routeCollection;
15 ClientValidationRuleFactory = (name, metadata) => ModelValidatorProviders. Providers. GetValidators (metadata ?? ModelMetadata. FromStringExpression (name, ViewData), ViewContext). selectiterator (v => v. GetClientValidationRules ());
16}
Copy code
Finally, we can see that within the GetUnobtrusiveValidationAttributes method, MVC calls the ClientValidationRuleFactory delegate to obtain the clientRules object. Its type is IEnumerable <ModelClientValidationRule>, in this way, the Client Validation data marked on the Model is output to the browser.
-------------------------------------- Feng Yi split line -------------------------------------------------
Through the above analysis, we know how the Server outputs Client Validation data, so how does JavaScript verify it?
Next we will analyze the source code of jquery. validate. unobtrusive. js, which implements the client verification logic of MVC.

From the rain of November

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.