This article only helps you understand the presentation of ASP. net mvc Model (only this article series 3)

Source: Internet
Author: User

Purpose

Let's look at a small example. In an ASP. net mvc project, create a controller Home with only one Index:

   model =  DemoModel {Email =    Email { ; 

Create a strong view

<fieldset>    <legend>DemoModel</legend>    <div >=></div></fieldset>

Run the following command:

An Email link is generated. Let's take a look at the html source file corresponding to the email:

         test@test.com 

For those who do not want to solve the problem, this is normal, just like 1 + 1 = 2. But for those who are diligent in learning and asking, the question is coming.

Why is an email link not a plain text?

Because I used DataType to indicate that it is an email!

How does DataType guide the Model to generate html?

If you are interested in these questions, please take a look.

 

Model brother -- ModelMetadata

Before introducing how the Model can be normally displayed in the View, you have to mention its brother ModelMetadata class. ModelMetadata describes features of a Model (such as the Model type, Model value, and template to be displayed ), all attribute values of the Model are described (recursive structure ). With this brother, the Model can know how to Display normally in the View. [Note: this refers to the series extension methods of HtmlHelper (such as Display/DiaplayFor/EditorFor) method is displayed in View. If you directly retrieve the Model value in the View and display it in html, you do not need to worry about ModelMetadata. But !! Don't think that you don't need to understand ModelMetadata, because another core in MVC is closely related to IT-Model binding and verification, so I suggest you first get to know this good brother]Let's see what this brother looks like:

       Type _modelType;                  _propertyName;            _model;                           Func<> _modelAccessor;             IEnumerable<ModelMetadata> _properties;             DataTypeName { ;    Description { ;    DisplayFormatString { ;    DisplayName { ; 
(_modelAccessor != == IEnumerable<ModelMetadata> (_properties == <ModelMetadata> originalProperties === ReadOnlyCollection<ModelMetadata> ModelMetadataProvider Provider { ; ; } TemplateHint { ; ; }

However, this class is not used by default in MVC, but its subclass CachedDataAnnotationsModelMetadata (in fact, there is also a CachedModelMetadata class in the middle, because this class is only a simple encapsulation, in order to facilitate understanding, omitted here ). One of the most important tasks of CachedDataAnnotationsModelMetadata is to get the Annotation Feature values on the Model through a series of Compute functions, and assign these values to the corresponding attributes. As follows:

      CachedDataAnnotationsModelMetadata : CachedModelMetadata<CachedDataAnnotationsMetadataAttributes> CachedDataAnnotationsModelMetadata(CachedDataAnnotationsModelMetadataProvider provider, Type containerType, Type modelType,  propertyName, )            : (provider, containerType, modelType, propertyName,  CachedDataAnnotationsMetadataAttributes(attributes.ToArray())                       }           (.DataType !=  
DataTypeName{ get{ ComputeDataTypeName();}} }

Pay attention to the two red parts in the Code. The Model Annotation Feature is included in PrototypeCache, so that the Annotation Feature value can be obtained through reflection. For example, In the CachedDataAnnotationsModelMetadata object corresponding to the DemoModel attribute Email at the beginning of the article, DataTypeName is assigned as "EmailAddress". After introducing the next heavyweight, you will explain the specific call process.

ModelMetadata creator ModelMetadataProvider

We also want to know the author of ModelMetadata, a heavyweight character:

    IEnumerable<ModelMetadata> GetMetadataForProperties(  ModelMetadata GetMetadataForProperty(Func<> modelAccessor, Type containerType,   ModelMetadata GetMetadataForType(Func<>

It is a pure abstract class. The first subclass of this class is very important. Let's take a look at the Code:

     ApplyMetadataAwareAttributes(IEnumerable<Attribute> (IMetadataAware awareAttribute  attributes.OfType<IMetadataAware>  ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<> modelAccessor, Type modelType,   ModelMetadata GetMetadataForType(Func<>            AttributeList attributes =                         ModelMetadata result = CreateMetadata(attributes,  , modelAccessor, modelType,   

Note that the red part allows you to implement the IMetadataAware interface through custom extensions to reprocess ModelMetadata.

 

According to the ModelMetadata description above, we know that the default class CachedDataAnnotationsModelMetadata is used in MVC, so it corresponds to the final subclass of ModelMetadataProvider CachedDataAnnotationsModelMetadataProvider.

When you want to obtain ModelMetadata through GetMetadataForType, CreateMetadata is called internally.PrototypeCall CreateMetadataPrototype or CraeteMetadataFromPrototype to implement the final creation process:

  CachedDataAnnotationsModelMetadataProvider : CachedAssociatedMetadataProvider<CachedDataAnnotationsModelMetadata>  CachedDataAnnotationsModelMetadata CreateMetadataPrototype(IEnumerable<Attribute> attributes, Type containerType, Type modelType,   CachedDataAnnotationsModelMetadata(  CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(CachedDataAnnotationsModelMetadata prototype, Func<> 

Like the MVC route table RouteTable, ModelMetadataProvider also has a static ModelMetadataProviders variable Current to provide the default ModelMetadataProvider. The simplified code is as follows:

();        }        public static ModelMetadataProvider Current        {            get { return _instance._currentProvider; }            set { _instance._currentProvider = value; }        }    }
Ultimate decryption

After learning about the two heavyweight members, let's go back to the code at the beginning of the article:

Html.DisplayFor(model => model.Email)

When this sentence is executed in the View, the extension function of HtmlHelper is executed to formally enter the long journey of generating MvcString:

The red line is the main process of program execution. Later, the home scene of execution was completed in TemplateHelpers.

The yellow line shows that ModelMetadata is created by calling the static function FromLambdExpression ---> GetMetadataFromProvider of ModelMetadata.

Let's take a look at the orange part. In MVC, there is a defadisplaydisplaytemplates class that stores data-type templates such as Boolean, String, Html, and Email. Finally, MVC uses ModelMetadata in ViewData. find the corresponding template for the DataType value, and finally complete the HTML string output, as WebViewPage. part of ExecutePageHierarchy. net mvc View display (only this article series II )).

 

Conclusion

This article uses a DataType attribute of ModelMetadata as an example to show you how the Annotation Feature added to the Model is used by ModelMetadata. Many other Model annotation features (such as ReadOnlyAttribute/RequiredAttribute/UIHintAttribute) are similar to this principle.

I hope the novice can understand it and the veteran will give more comments. If you think it is helpful to you, please let more people know about it :)

Related Article

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.