ASP. net mvc Model metadata (4)

Source: Internet
Author: User

ASP. net mvc Model metadata (4)Preface

The previous sections explain the process of Model metadata generation, and do not explain the internal and Model metadata structure of the Model metadata generation process in detail. After reading this article, I will have a better understanding of the Model metadata, and of course it will not be particularly comprehensive, because there will be space later. We hope this will bring you good results.

 

Model Metadata
  • What is Model?Metadata?
  • Generate ModelMetadata process [1]
  • Generate ModelMetadata process [2]
  • ModelMetaDataDefinition and Explanation
  • ModelMetadata application (common feature application)-1
  • ModelMetadata application (custom view template)-2
  • ModelMetadata application (IMetadataAwareInterface Usage)-3

 

ModelMetaData definition and Explanation

Can we define the generation of Model metadata by ourselves? The answer is yes. You must. The MVC Framework provides a top-level base class, which gets the default system implementation class (or our custom implementation class) from the current context during the call ). Let's take a look at the sample code 1-1.

Code 1-1

 public class MyCustomModelMetadataProvider:DataAnnotationsModelMetadataProvider    {        protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)        {            DataAnnotationsModelMetadata result = new DataAnnotationsModelMetadata(this, containerType, modelAccessor, modelType, propertyName, displayColumnAttribute);            return result;        }    }

The MyCustomModelMetadataProvider type in code 1-1 inherits from the DataAnnotationsModelMetadataProvider type and overwrites the CreateMetadata () method () the method will assign values to the attributes of the Model metadata based on the attribute information in the attributes parameter. As mentioned below, attributes parameters are not parsed in code 1-1, but a Model metadata type (DataAnnotationsModelMetadata inherited from ModelMetadata) is instantiated for return. After the definition is completed, the system does not call our custom implementation, but needs to be added to the system context when the project is started. add sample code 1-2 in the Application_Start () method of the MvcApplication type in the asax file.

Code 1-2

ModelMetadataProviders.Current = new MyCustomModelMetadataProvider();

After this definition, the system framework will call our custom implementation during execution. You can also use the preceding example to directly run it, I have not tried any results, but it certainly won't have any special effect. The real purpose is not to, but to set a breakpoint at the entrance of the CreateMetadata () method (figure 1) then we press F5 to execute the program again, and the program will execute the CreateMetadata () method of our custom implementation.

Figure 1

What is the significance of the above? This means that when a breakpoint comes in, we can open the instant debugging window and input CreateMetadata () the modelType of the method parameter is used to view the type or attribute of the Model metadata to be generated, which is also easier for us to learn. It also proves the process of generation as I mentioned in the previous article.

Next, let's take a look at how the Model metadata is operated in the default DataAnnotationsModelMetadataProvider type provided by the system. Let's take a look at the default implementation code,

Code 1-3

protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)        {            List<Attribute> attributeList = new List<Attribute>(attributes);            DisplayColumnAttribute displayColumnAttribute = attributeList.OfType<DisplayColumnAttribute>().FirstOrDefault();            DataAnnotationsModelMetadata result = new DataAnnotationsModelMetadata(this, containerType, modelAccessor, modelType, propertyName, displayColumnAttribute);                        // Do [HiddenInput] before [UIHint], so you can override the template hint            HiddenInputAttribute hiddenInputAttribute = attributeList.OfType<HiddenInputAttribute>().FirstOrDefault();            if (hiddenInputAttribute != null)            {                result.TemplateHint = "HiddenInput";                result.HideSurroundingHtml = !hiddenInputAttribute.DisplayValue;            }            // We prefer [UIHint("...", PresentationLayer = "MVC")] but will fall back to [UIHint("...")]            IEnumerable<UIHintAttribute> uiHintAttributes = attributeList.OfType<UIHintAttribute>();            UIHintAttribute uiHintAttribute = uiHintAttributes.FirstOrDefault(a => String.Equals(a.PresentationLayer, "MVC", StringComparison.OrdinalIgnoreCase))                                              ?? uiHintAttributes.FirstOrDefault(a => String.IsNullOrEmpty(a.PresentationLayer));            if (uiHintAttribute != null)            {                result.TemplateHint = uiHintAttribute.UIHint;            }            EditableAttribute editable = attributes.OfType<EditableAttribute>().FirstOrDefault();            if (editable != null)            {                result.IsReadOnly = !editable.AllowEdit;            }            else            {                ReadOnlyAttribute readOnlyAttribute = attributeList.OfType<ReadOnlyAttribute>().FirstOrDefault();                if (readOnlyAttribute != null)                {                    result.IsReadOnly = readOnlyAttribute.IsReadOnly;                }            }            DataTypeAttribute dataTypeAttribute = attributeList.OfType<DataTypeAttribute>().FirstOrDefault();            DisplayFormatAttribute displayFormatAttribute = attributeList.OfType<DisplayFormatAttribute>().FirstOrDefault();           // SetFromDataTypeAndDisplayAttributes(result, dataTypeAttribute, displayFormatAttribute);            ScaffoldColumnAttribute scaffoldColumnAttribute = attributeList.OfType<ScaffoldColumnAttribute>().FirstOrDefault();            if (scaffoldColumnAttribute != null)            {                result.ShowForDisplay = result.ShowForEdit = scaffoldColumnAttribute.Scaffold;            }            DisplayAttribute display = attributes.OfType<DisplayAttribute>().FirstOrDefault();            string name = null;            if (display != null)            {                result.Description = display.GetDescription();                result.ShortDisplayName = display.GetShortName();                result.Watermark = display.GetPrompt();                result.Order = display.GetOrder() ?? ModelMetadata.DefaultOrder;                name = display.GetName();            }            if (name != null)            {                result.DisplayName = name;            }            else            {                DisplayNameAttribute displayNameAttribute = attributeList.OfType<DisplayNameAttribute>().FirstOrDefault();                if (displayNameAttribute != null)                {                    result.DisplayName = displayNameAttribute.DisplayName;                }            }            RequiredAttribute requiredAttribute = attributeList.OfType<RequiredAttribute>().FirstOrDefault();            if (requiredAttribute != null)            {                result.IsRequired = true;            }            return result;        }

In code 1-3, we can see that the attributeList variable is converted to the Attribute set type based on the attributes parameter, and then the first DisplayColumnAttribute Type feature is searched in this set, I don't know what this feature type is for the moment, because I don't quite understand it now.

Then, a DataAnnotationsModelMetadata type metadata is instantiated based on the parameters in the CreateMetadata () method. This type is described above. Next, we get the first HiddenInputAttribute Type feature instance from the attributeList variable. After judging that it is not empty, assign values to the two attributes of the result variable of the Model metadata DataAnnotationsModelMetadata type (the result of the Model metadata DataAnnotationsModelMetadata type variable is collectively referred to as result). The first is the TemplateHint attribute of the Model metadata, this attribute indicates the view template used by the object represented by the Model metadata to generate Html code (the content of the view template is described later in this series. Let's look back later, learning is an iterative process ). The value assignment of the HideSurroundingHtml attribute corresponds to the DisplayValue of the HiddenInputAttribute type. The HiddenInputAttribute type indicates whether to display the attribute or field value as a hidden Input element, if we write this statement [HiddenInput (DisplayValue = false)], and the value of HideSurroundingHtml is true, it indicates that the object model is presented using the associated Html elements, this means that the hidden input field associated with the HiddenInputAttribute type is used to present the specified attribute or field. It may be a bit difficult here, but it will not be difficult. The effect of the example will be discussed in the next section.

Switch back to the topic. Next we will get a set of UIHintAttribute types from attributeList. After some judgment, we will get a UIHintAttribute instance and assign it to the TemplateHint attribute (as mentioned above ), here we will overwrite it. We should pay attention to this when using the default Model metadata provider, and continue to look down.

Get the first EditableAttribute instance from attributeList, and set the IsReadOnly attribute value of result based on the AllowEdit attribute value in the EditableAttribute type instance, which indicates whether the model is read-only, the EditableAttribute type indicates whether the model can be edited. The meaning of the EditableAttribute type is similar to that of the ReadOnlyAttribute type below, except that the attribute values set in the two types of read-only effects are the opposite.

The first DataTypeAttribute type instance that meets the type conditions is also obtained from attributeList, And the DisplayFormatAttribute type instance is also available. Here, another function in the default provider is called, I will not discuss it here. I just want to explain it a little bit. Why put the two together? Because they are all related to the settings of the specified model output format.

The ScaffoldColumnAttribute type instance indicates whether to use the base frame (one of the template view guides, EditorForModel is one of them). When this feature class is used for a certain attribute, this attribute is skipped directly when the base frame is used, and is not found on the generated page. (Abandoned)

An instance of the same DisplayAttribute type is also the first instance to obtain the type that meets the type conditions from attributeList. A DisplayAttribute in the instance of the DisplayAttribute type will be set to the DisplayName attribute of the result, this attribute indicates the value displayed on the page for the specified model. The meaning of the DisplayNameAttribute type instance is similar to that of the DisplayAttribute type, except that the DisplayNameAttribute type can be used for the class type.

Finally, the meaning of the RequiredAttribute type instance is described in the Model verification section.

 

 

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.

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.