As we have mentioned in the previous article, the model metadata customization is achieved by applying the corresponding features to the data type of the model, which is extremely attribute to the member. Most of these attributes for declarative metadata definitions are defined in the System.ComponentModel.DataAnnotations.dll assembly, where the name of the assembly is also the corresponding namespace name, so we can use them for the data annotation attribute Annotation, let's go over some of the commonly used data annotation features and how they affect meta data.
First, Uihintattribute
HtmlHelper and Htmlhelper<tmodel> define a series of model based template methods, such as Display/displayfor, Editor/editorfor, displayformodel/ Editformodel, Lable/labelfor and Displaytext/displaytextfor. The so-called template method, that is, we call these methods to represent the model of the data in the view, not to the final rendering of the UI elements of a loss of control, and the default or specified template to determine the final rendering in the browser HTML. Each specific template has the corresponding name, these template methods in the model rendering, according to the corresponding model metadata to get the corresponding template name. Specifically, the name of the template is represented by the Modelmetadata templatehint attribute, as shown in the following code fragment, which is a read-write property of a string type.
1:public class Modelmetadata
2: {
3: //other Members
4: Public virtual string Templatehint{get;set;}
5:}
Modelmetadata's Templatehint properties can be customized by the Uihintattribute feature. As shown in the following code snippet, Uihintattribute has Presentationlayer and uihint two read-only properties that restrict the type of presentation layer (such as "HTML", "Silverlight", "WPF", "WinForms , and the name of the template, both of which are initialized in the constructor.
1: [AttributeUsage (Attributetargets.field | Attributetargets.property, Allowmultiple=true)]
2:public class Uihintattribute:attribute
3: {
4: //other Members
5: Public Uihintattribute (string uiHint);
6: Public Uihintattribute (string uiHint, string presentationlayer);
7:
8: Public string Presentationlayer {get;}
9: Public string UIHint {get;}
10:}
It is not hard to see, by applying the AttributeUsageAttribute definition on Uihintattribute, that because its AllowMultiple property is set to True, means that we can apply multiple Uihintattribute attributes on the same target element, so which one will be chosen to customize the model metadata?
If multiple uihintattribute are applied to the appropriate element (type or attribute), first select a Presentationlayer property of "MVC" (case-insensitive) Uihintattribute. If such a uihintattribute does not exist, select a Uihintattribute with an Presentationlayer property value of NULL. It is worth mentioning that if there are multiple matching uihintattribute controllable selection, the system will choose the first one, but the order of the attributes obtained by reflection is not directly related to the attribute being labeled.
Next we demonstrate the impact of the Uihintattribute feature on the model metadata and the selection strategy for multiple Uihintattribute applied to the same target element through a simple example. In view of reusability, we have written a static helper method getmodelmetadata<tmodel> to get model metadata for model type TModel for the specified property.
1:public static Modelmetadata getmodelmetadata<tmodel> (String propertyname)
2: {
3: Modelmetadataprovider Provider = modelmetadataproviders.current;
4: modelmetadata containermetadata = new Modelmetadata (provider, NULL, () => null, typeof (TModel), null);
5: Return ContainerMetadata.Properties.FirstOrDefault (m => m.propertyname = = propertyname);
6:}
We define a type model data type by using the following code, three properties Foo, bar, and Baz define it. For the property bar, we also applied the Uihintattribute attribute of the two template names "Template A" and "Template B" respectively, which used the character "MVC" as the value of the Presentationlayer parameter. Attribute Baz general application of the Uihintattribute feature based on the template name "Template a".
1:public class Model
2: {
3: Public string Foo {get; set;}
4:
5: [UIHint ("Template A")]
6: [UIHint ("Template B", "MVC")]
7: Public string Bar {get; set;}
8:
9: [UIHint ("Template A")]
Public string Baz {get; set;}
11:}
Now we write the following test program in a console program. We created the modelmetadata of three attributes for Foo, bar, and Baz defined in the data type model by using the helper method defined above getmodelmetadata<tmodel>. and the corresponding Templatehint properties are printed separately.
1:modelmetadata foo = getmodelmetadata<model> ("foo");
2:modelmetadata bar = getmodelmetadata<model> ("bar");
3:modelmetadata baz = getmodelmetadata<model> ("Baz");
4:
5:console.writeline ("foo: {0}", foo. Templatehint?? " N/a ");
6:console.writeline ("bar: {0}", bar.) Templatehint?? "N/a");
7:console.writeline ("Baz: {0}", Baz.) Templatehint?? "N/a");
The above test program will produce the following output on the console, which is the customization of the Uihintattribute feature for model metadata described above. And the selection strategy for multiple Uihintattribute features that apply to the same target element is consistent.
1:foo:n/a
2:bar:template B
3:baz:template A