ASP. NET Web API Model-ModelMetadata,

Source: Internet
Author: User

ASP. NET Web API Model-ModelMetadata,
ASP. NET Web API Model-ModelMetadata Preface

The previous sections mainly focus on the execution process of the controller. However, the knowledge points contained in the execution process are too large and can only be explained in part, in the last two articles, we can see that after the Controller Method selector selects the Controller method based on the request, it will generate the corresponding description object and enter the filter execution process, we will also talk about the series of operations on the Model after the authorization filter is executed, including Model metadata parsing, Model binding, and Model verification, finally, it will be executed through the unique method of the Web API framework, namely the ParameterBinding parameter binding. After these operations are completed, the behavior filter will be executed and can be intercepted before and after the Controller method is executed, in terms of technology, this is a kind of implementation of the AOP idea. In terms of business logic, it is also a kind of dependency injection. This article will talk about ASP. the Model metadata in the NET Web API framework, that is, ModelMetadata.

 

Model-ModelMetadata (Object introduction and basic knowledge)

Before explaining Model binding, I will explain the Model metadata in the Web API, ASP in front of me. net mvc series summary has explained the metadata of the Model in the MVC Framework. If you have any knowledge of MVC, you can go and see it in ASP. the design idea of the Model metadata in the NET Web API framework is the same as that in the MVC framework. It parses the type of the Model, and then presents the tree structure or uses it wherever it is needed. Why is it a tree structure? Let's take a look at the example. Next we will be able to understand it with the help of object types.

 

No matter how it is expressed in the framework, let's take a look at the defined Model:

Sample Code 1-1

Public class EmployeesInfo {[Display (Description = "employee Name")] public string Name {get; set;} [Display (Description = "Employee age")] public int Age {get; set;} [Display (Description = "")] public string Sex {get; set ;} [Display (Description = "Employee Address information")] public Address AddressInfo {get; set ;}} public class Address {[Display (Description = "Address information")] public string AddressInfo {get; set;} [Display (Description = "zip code")] public string ZipCode {get; set ;}}

In code 1-1, I defined a Model with the EmployeesInfo type to indicate employee information. There are several attributes in this Model. The AddressInfo attribute is the following Address type, this is to show that the object represented by the Model metadata has two types: simple and complex. As for how to judge this type, let's take a look at the sample code and the information contained after the Model is generated as the Model metadata by the framework.

Sample Code 1-2

Public class MetadataController: ApiController {public string Get () {EmployeesInfo employeesInfo = new EmployeesInfo () {Name = "JinYuan", Age = 24, Sex = "male ", addressInfo = new Address () {AddressInfo = "Nanjing", ZipCode = "210000" }}; ModelMetadata modelMetadata = this. configuration. services. getModelMetadataProvider (). getMetadataForType () => employeesInfo, employeesInfo. getType (); StringBuilder strBuilder = new StringBuilder (); ModelMetadataAnalysis (strBuilder, modelMetadata); return strBuilder. toString ();} private void ModelMetadataAnalysis (StringBuilder stringBuilder, ModelMetadata modelMetadata) {if (modelMetadata. isComplexType = true) {foreach (var metadata in modelMetadata. properties) {ModelMetadataAnalysis (stringBuilder, metadata) ;}} else {stringBuilder. appendLine (modelMetadata. description ). appendLine ("Value:" + modelMetadata. model );}}}

In code 1-2, I first defined a controller and a Get () method. The return type is string, and then the Model is instantiated in the Get () method, that is, the definition in code 1-1. After that, I obtain the Model metadata provider from the ServicesContainer Services Attribute Based on the Configuration of the HttpConfiguration type attribute contained in the current controller base class, this provider is used to generate Model metadata based on the Model type. The newly generated Model metadata, that is, the modelMetadata variable, is only a type representation, that is, the EmployeesInfo type, in addition, it does not contain the metadata of attributes in the EmployeesInfo type. Note that it is only temporary.

Next, we use the ModelMetadataAnalysis () method. First, we determine whether the current Model metadata represents a complex type. If so, we will read the Properties attribute in the Model metadata, note that when reading data, the modelMetadata parameter in the ModelMetadataAnalysis () method will start to use its own Model metadata provider to generate Model metadata for the properties of the type it represents. From this we can see that the above Code implementation only outputs simple types. Let's take a look.

Figure 1

As shown in figure 1, let's look at the implementation of code 1-2. Finally, let's take a look at the execution results.

Figure 2

As shown in figure 2, the returned results are accessed from both the client and the browser, both of which are the same.

 

The following describes the object types.

Figure 3

Let's first look at ModelMetadata.TypeIn Figure 3, we can see that the ModelMetadata type is in the namespace System. Web. Http. Metadata. Let's first look at the definition of ModelMetadata,

Sample Code 1-3

    public class ModelMetadata    {        public ModelMetadata(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName);        public virtual Dictionary<string, object> AdditionalValues { get; }        public Type ContainerType { get; }        public virtual bool ConvertEmptyStringToNull { get; set; }        public virtual string Description { get; set; }        public virtual bool IsComplexType { get; }        public bool IsNullableValueType { get; }        public virtual bool IsReadOnly { get; set; }        public object Model { get; set; }        public Type ModelType { get; }        public virtual IEnumerable<ModelMetadata> Properties { get; }        public string PropertyName { get; }        protected ModelMetadataProvider Provider { get; set; }        public string GetDisplayName();        public virtual IEnumerable<System.Web.Http.Validation.ModelValidator> GetValidators(IEnumerable<System.Web.Http.Validation.ModelValidatorProvider> validatorProviders);    }

The ModelMetadata type is defined in code 1-3. Let's start with the constructor.

There are five parameters in the constructor. Some of these parameters correspond to attributes. For the first parameter ModelMetadataProvider type, it corresponds to the Provider attribute in the ModelMetadata type, some may ask what this property is? As mentioned in the preceding example, when the Model metadata is of a complex type, you can obtain the Model metadata of the currently indicated type from the Properties attribute. What is the metadata generated when it is obtained? This is the metadata Provider corresponding to the Provider property. Here we also talk about the Properties property. From its definition, we can see that it is an attribute of the IEnumerable <ModelMetadata> type, that is why the tree structure shown above shows us why. The second parameter instance type in the constructor is the container type of the corresponding type represented by this metadata object. The third parameter is interesting, it is a Func <Object> delegate. It is used to obtain the Instance value of the type represented by the current metadata Object. This is the origin of the attribute value of the Model attribute in the ModelMetadata type, the fourth parameter is the object type corresponding to the current metadata, that is, it corresponds to the ModelType attribute value in the ModelMetadata type. The last parameter represents the attribute name and corresponds to the PropertyName attribute value in the ModelMetadata type.

Next we will talk about other attribute values in the ModelMetadata type. AdditionalValues indicates the container attribute. You can add any additional values as key-value pairs to represent them. In this framework, many objects will be designed, it can be of the object type, but the key-value queue is used here.

The IsComplexType attribute indicates whether the type represented by the current Model metadata object is a complex type. How can this problem be determined?

    public virtual bool IsComplexType    {        get        {            return !TypeHelper.HasStringConverter(this.ModelType);        }    }

Is to see whether the type can be converted to the String type.

The IsReadOnly attribute is described below, because there is only so much information obtained when initializing a Model metadata, while the IsReadOnly attribute is controlled through ModelAttribute.

 

Let's take a look at ModelMetadataProvider.

Sample Code 1-4

    public abstract class ModelMetadataProvider    {        protected ModelMetadataProvider();        public abstract IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType);        public abstract ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);        public abstract ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);    }

From code 1-4, we can see that the Model metadata provider ModelMetadataProvider has three abstract methods, which are also abstract classes. The meanings of these three methods can be explained to you.

The GetMetadataForProperties () method obtains the metadata types of all attributes in the container Based on the container instance and container type.

The GetMetadataForProperty () method is based on an attribute name that obtains the delegate, container type, and property metadata of the container instance.

The GetMetadataForType () method obtains the metadata of this type based on a type, but the delegate parameter must be able to obtain the instance of this type.

 

Next we will go back to code 1-2. where we get the Model metadata provider, we also mentioned where we got it. Now let's take a look at the specific type,

Sample Code 1-5

this.SetSingle<ModelMetadataProvider>(new DataAnnotationsModelMetadataProvider());

 

Let's take a look at DataAnnotationsModelMetadataProvider.Type.

Sample Code 1-6

    public class DataAnnotationsModelMetadataProvider : AssociatedMetadataProvider<CachedDataAnnotationsModelMetadata>    {        public DataAnnotationsModelMetadataProvider();        protected override CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor);        protected override CachedDataAnnotationsModelMetadata CreateMetadataPrototype(IEnumerable<Attribute> attributes, Type containerType, Type modelType, string propertyName);    }

Regardless of the DataAnnotationsModelMetadataProvider type, the returned type of the function defined in it is CachedDataAnnotationsModelMetadata.

 

CachedDataAnnotationsModelMetadataType

Sample Code 1-7

    public class CachedDataAnnotationsModelMetadata : CachedModelMetadata<CachedDataAnnotationsMetadataAttributes>    {        public CachedDataAnnotationsModelMetadata(CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor);        public CachedDataAnnotationsModelMetadata(DataAnnotationsModelMetadataProvider provider, Type containerType, Type modelType, string propertyName, IEnumerable<Attribute> attributes);        [SecuritySafeCritical]        protected override bool ComputeConvertEmptyStringToNull();        [SecuritySafeCritical]        protected override string ComputeDescription();        [SecuritySafeCritical]        protected override bool ComputeIsReadOnly();    }

From code 1-7, we can see that the CachedDataAnnotationsModelMetadata type inherits from the CachedModelMetadata <CachedDataAnnotationsMetadataAttributes> type, that is, the CachedModelMetadata <TPrototypeCache> type.

Let's take a look at CachedModelMetadata <TPrototypeCache>Type

Code 1-8

public abstract class CachedModelMetadata<TPrototypeCache> : ModelMetadata    {        protected CachedModelMetadata(CachedModelMetadata<TPrototypeCache> prototype, Func<object> modelAccessor);        protected CachedModelMetadata(DataAnnotationsModelMetadataProvider provider, Type containerType, Type modelType, string propertyName, TPrototypeCache prototypeCache);        public override sealed bool ConvertEmptyStringToNull { get; set; }        public override sealed string Description { get; set; }        public override sealed bool IsComplexType { get; }        public override sealed bool IsReadOnly { get; set; }        protected TPrototypeCache PrototypeCache { get; set; }        protected virtual bool ComputeConvertEmptyStringToNull();        protected virtual string ComputeDescription();        protected virtual bool ComputeIsComplexType();        protected virtual bool ComputeIsReadOnly();    }

How can we see this mess? It's so messy !!!! Don't panic.

As mentioned above, the Model metadata will have a lot of initial values during initialization, but have you ever thought about the real role of the Model metadata? During initialization, we can say that our Model metadata already contains some basic information about the object type and value, but we need to add additional actions to the Model, for example, if the control of this XX attribute is read-only or the display mode of the XX attribute is changed, this kind of thing cannot be done by the Model metadata during initialization. What should we do?

Look at the four methods starting with Compute in code 1-8. These four methods are used to obtain the set action and then set it to the Model metadata, the implementation is not the expected result, but the CachedDataAnnotationsModelMetadata type defined in code 1-7. In code 1-7, the CachedDataAnnotationsModelMetadata type inherits the CachedModelMetadata <metadata> type, now let's take a look at the definition of the CachedDataAnnotationsMetadataAttributes type.

 

CachedDataAnnotationsMetadataAttributesType

Sample Code 1-9

    public class CachedDataAnnotationsMetadataAttributes    {        public CachedDataAnnotationsMetadataAttributes(IEnumerable<Attribute> attributes);        public System.ComponentModel.DataAnnotations.DisplayAttribute Display { get; protected set; }        public System.ComponentModel.DataAnnotations.DisplayFormatAttribute DisplayFormat { get; protected set; }        public System.ComponentModel.DataAnnotations.EditableAttribute Editable { get; protected set; }        public ReadOnlyAttribute ReadOnly { get; protected set; }    }

The CachedDataAnnotationsMetadataAttributes type in code 1-9 is applied to the encapsulation of multiple types of metadata features. For the moment, we do not need to know what the CachedDataAnnotationsMetadataAttributes type is. Now let's go back to code 1-7 to see the specific implementation methods of those methods.

Code 1-10

    [SecuritySafeCritical]    protected override string ComputeDescription()    {        if (base.PrototypeCache.Display == null)        {            return base.ComputeDescription();        }        return base.PrototypeCache.Display.GetDescription();    }

I have selected one of them. Here we can clearly see that we want to call the PrototypeCache attribute in the base class. What type does the PrototypeCache attribute correspond?

You can see what type the PrototypeCache attribute corresponds to in code 1-8. It is a generic type. When the CachedDataAnnotationsModelMetadata type is inherited, we can see the generic type in code 1-7, that is, the type defined in code 1-9.

 

Finally, let's take a look.

Figure 4

Finally, some initial values will be initialized when the Model metadata is initialized. For behavior settings on the Model, you need to execute the settings through the CachedDataAnnotationsMetadataAttributes type, the type of several attributes corresponding to the CachedDataAnnotationsMetadataAttributes type can be found at a glance.

 

 

Author: Jin Yuan

Source: http://www.cnblogs.com/jin-yuan/

The copyright of this article is shared by the author and the blog Park. You are welcome to reprint this article. However, you must keep this statement without the author's consent and go to the Article Page.


WEB APIs are different from web mvc APIs.

WebAPI is added to the new MVC to provide a REST-style WebService. The new WebAPI project is the same as the typical MVC project, including the main Models, Views, Controllers and other folders and Global. asax file. Views is not very useful for webapis. The Model in Models is mainly used to save the objects for interaction between the Service and the Client. By default, these objects are converted to Json format for data transmission in two rows, the Controller in Controllers is a Resource corresponding to WebService and is used to provide services. Like common MVC, Global. asax is used to configure routing rules.
For a WebAPI, ingress is initially designed as the same as that of the WCF producer client and server. Currently, the ingress we haven't mentioned yet because our request is encapsulated the HTTP request rule is used to receive responses such as AJAX and Form submission.

What is a web api?

Web APIs are network application interfaces.
Today's web computing platform contains a wide range of functions, most of which can be accessed through APIS (application programming interfaces. Simplified
Single Social bookmarking service del. icio. us, to a much more complex amazon s3 'fully virtualized storage platform, think about what to do with these web APIs, it's amazing.
The web platform is classified into six basic facilities, and some related products are briefly outlined. The clue is that these products provide APIs, which means that they can be integrated by other services.
Storage Service: The Storage Service focuses on abstract and Virtualized Storage. The leader in this field is amazon s3, which has been discussed in depth in my article le in web 2.0 journal. For developers, S3 provides extremely streamlined and abstract APIs such as hash tables, allowing you to easily access information.
Another interesting service is openemy, which provides APIs similar to file system interfaces, but adds the ability to label files. Today
Earlier in the year, TechCrunch analyzed some other online storage services. But so far we have not seen the legendary disruptive storage services GDrive (from google) and LiveDrive (from Microsoft). They are likely to provide APIs.
Message Service: The concept of message service is similar to the traditional middleware. Due to technical and commercial complexity, they have not yet been developed on a large scale. In the short term, the visible web-based communication Service is Amazon Simple Queue Service. This service makes it easier for any application to communicate securely and elastically Based on queues.
Computing Service: Currently, there is no general web computing service black box that can be accessed through APIS, but many technologies point to this direction. One is alexavertical search platform, which will be mentioned in the following search Service Section. The second is grid computing, such as sungrid, datasynapse's gridserver or platform's symphony.
Encapsulating arbitrary computing tasks in APIS is a very challenging task. It may take many years for such services to become popular.
Information Service: Information Service provides massive and specific information. Including geographic data like Google Maps APIs, product data like Amazon E-Commerce and Amazon historcal Pricing Services, and the latest Yahoo! Answer's API login. What these services have in common is that they all provide
Simple APIs to access massive data may lead to unpredictable cross-application of isolated information.
Search Service: because of its basic and dominant position in the web field, search service forms a key part of the new web infrastructure. Google search
Api is a typical search abstraction mechanism earlier in the past. Another example is alexa search platform, which is designed to drive a series of vertical search engines that challenge google's position. It is quite interesting that, technically, alexa search platform is more like a computing service, but it is limited to the search field. This means the possibility of other services, such as sorting services or Data Conversion Services.
Web Service: The last broad type of Web Service is called. Its names may not be specific, but they include del. icio. us, flickr, and basecamp.
. John Musser compiled some very influential APIs in Programmableweb.
These specific services will become users of the above-mentioned services in the future, but their value is more reflected in their clear,
Specific and simple APIs to view and change your information. Although they look more like molecules than atoms, they are such basic services in today's web field, so it makes sense to regard them as components .... Remaining full text>

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.