Http://www.cnblogs.com/lzhp/archive/2013/03/25/2981650.html
The MVC Model Series is divided into three main parts: Model Templates,model Binding,model Validation. The main content of this article includes the following three parts:
A. Using the Template view Helper
B. Customizing the View template system
C. Understanding Metadata Delivery System
One, using the template View Assistant 1.1 assistant Experience
Template View helper, I understand that MVC provides an assistant for generating view labels based on the data types defined in model. Obviously, the benefit is that when we change the data type in model, we don't have to worry about changing the view. Let's try it out here.
First build an empty MVC solution named Modeltemplate, such as
And then create a new class in models, just for demonstration purposes, so we don't separate the following three classes
Define people class public class persons {public int PersonId {get; set;} public string FirstName {get; set;} public string LastName {get; set;} Public DateTime BirthDate {get; set;} Public Address homeaddress {get; set;} public bool isapproved {get; set;} Public role role {get; set;} } Define the person address class public class address {public string Line1 {get; set;} public string Line2 {get; set;} public string City {get; set;} public string PostalCode {get; set;} public string Country {get; set;} } Define a person role class public enum role { Admin , User, Guest }
Then add a homecontrol in the controllers and add the following code to index:
Person MyPerson = new person { PersonId = 1, FirstName = "Li", LastName = "Friend", BirthDate = DATETIME.PA RSE ("1988-1-15"), homeaddress = new Address { Line1 = "Cangshan", Line2 = "nan Hou Jie", City = "Fuzhou", Country = "China", PostalCode = "350000" }, isapproved = True, Role = Role.user }; Return View (MyPerson);
Next, create a solution, right-click on index and add a view:
Add the following code to the view and run
The result of the operation is:
You will find that the MVC framework generates input and a checkbox for us based on the data types we define. When we change isapproved to a string, we run the result as:
Without changing the front end, the same Template view helper generates input based on the type. is the template view helper useful? In addition to generating input can also generate other, if we want to let the front-end display is read-only, you can use: @Html. Displayfor (x=>x.isapproved). The result of the operation is:
In addition to the use of strongly typed, you can also use the following usage, followed by a string that directly follows the field: @Html. DisplayText ("isapproved"), the result is consistent with the above.
In addition to the above @html.displayfor (x=>x.isapproved), html.editorfor (x =>x.firstname), and Html.display ("FirstName"), Html.label ("FirstName"), Html.labelfor (x=> x.firstname), Html.displaytext ("FirstName"), html.displaytextfor (x = >x.firstname) can be used. If you want to know a clear word, you can try it yourself. It is recommended that you use strongly typed representations to reduce errors. Note the HTML for the source file generated above:
1.2 Bracket TemplateWe have experienced the thrill of the template helper, and there is a problem, since he will judge the fields to be generated based on the type, and if we want to see all the fields, are we going to hit them all? There's got to be a more concise way, and that's what we're looking at. A stent template with three Displayformodel,editorformodel,labelformodel. If we want to show all the fields above, we'll try it with a editorformodel. In order to see the generated checkbox, I changed the isapproved to a Boolean type.
Is it quicker than our original method? Quickly and carefully you will surely find the problem above
A. The time field is longer, B. The Address field is not displayed C. also shows the user ID, usually we do not want users to see this thingIf you are the one who pursues perfection, then you must first think
D. The lable label shown is in English and I want to see the ChineseIt seems that the stent template is not ideal ah, there are so many problems. Let's go to one by one to solve the problem above. Before we solve the problem, let's introduce a noun, metadata (Metadata) Here you'll think of him as some label for the Description field. And then we'll solve the problem in one by one.
A solution to the problem is to use
[DataType (Datatype.date)]
Public DateTime BirthDate {get; set;}
In the datatype above press F12, will find actually an enumeration type, the specific function can see its summary. You can also set the type to other. Here is not a description.
B: The solution to the problem: first analyze why the address can not be displayed, because the type of the address is a class, not a simple type, so our framework in order to respect this class, does not infer the type of its field, So only use the previous @html.editorfor (m=>m.homeaddress), we list the Address field, we can infer.
C: There are two ways to solve the problem, one is simply to show that you don't have to put the ID in the HTML with the hidden tag, one to manipulate it, for example, to modify it, we usually use the ID as an identifier, just to hide it.
Here are two ways to solve the problem:
1, [Scaffoldcolumn (false)]//front end does not display hidden
public int PersonId {get; set;}
2, [Hiddeninput (Displayvalue=true)] If true, the front end will render the value and the front-end generated hidden, if false, the front-end only generated hidden
D The workaround is to use [Display (name= ")]. Next look at the results shown:
For metadata, there is also a [UIHint ("")] is not used, its role is to display the original property type as specified type, its "" can be Boolean, Collection, Decimal, EmailAddress, Hiddeninput, Hiddeninput, Multilinetext, Object, Password, String, Text, Url. Its display results according to the meaning can be seen, specific to MSDN or reference old a article, if not converted, will error, such as the conversion of a string into a Boolean, will prompt cannot be converted.
In addition, there is a more important [Metadatatype (typeof (ClassName))] metadata, often used in the ORM aspect, because the ORM generated entity if modified, after compiling the modified content will be deleted, so you can use
This metadata merges two classes together to work together. But the premise is to declare the class as partial, and the following people as an example:
Let's assume that the following class is generated for ORM:
public partial class Person {public int PersonId {get; set;} public string FirstName {get; set;} public string LastName {get; set;} Public DateTime BirthDate {get; set;} Public Address homeaddress {get; set;} public bool isapproved {get; set;} Public role role {get; set;}}
With the Metadatatype data source to work with the Personmetadatasource class, mainly to let the surname multiline display, the code is as follows:
[Metadatatype (typeof (Personmetadatasource))] public partial class person { } public partial class Personmetadatasource { [UIHint (" Multilinetext ")] public string FirstName {get; set;} }
It is:
For the other two bracket template usage is similar, do not repeat here.
Second, custom view template System 2.1 Example of custom templatesSometimes we want the specified value to appear as the effect we want, so we should be able to use a custom view template. For example, the user role wants to have a DDL effect, of course, you can use Html.dropdownlistfor, there is another way is to create a new file in the ~/views/shared folder EditorTemplates, add a view, But this is a partial view. :
Note that the view name must be consistent with the type shown earlier, and this is consistent with role, because the time to display the file name (type name) is the parameter to be searched. Inconsistent words, is not found. Paste the following code into the file you just created:
@using Modeltemplate.models@model role<select id= "role" name= "role" > @foreach (role value in Enum.getvalues ( typeof (Role)) { <option value= "@value" @ (Model = = value?) "Selected=\" selected\ "" "" "") > @value </option> }</select>
Run to see the user role is displayed using DDL, of course, there is a benefit is the reuse, and other use of the field of the view will be rendered in DDL, if only want to display in a controller, you can use the/views/<controller>/ EditorTemplates, the path is a specified path, cannot be changed, and cannot change the editortemplate to another letter.
The following are displayed for the user role:
2.2 Order of using templatesThink of you, see the example above, you will certainly want to why not use the original template, and use a custom template, then what time to use the built-in template? There is a sequence in this. The order of the following is slightly listed below:
1.html.editorfor (M = m.someproperty, "MyTemplate") because we have developed to use the MyTemplate template, so ranked first.
2. Templates that have been assigned metadata, such as UIHint
3. A template associated with the data type specified as metadata, such as the datatype attribute
4. Customizing templates in EditorTemplates, DisplayTemplates (and Editortemplate)
5. Finally, the built-in template
Note: The above 2 and 3 are easy to confuse. One is the metadata template, and the other is the metadata data type. We can use an example to illustrate the wrapper isapproved field.
Using UIHint and datatype as well as custom templates to illustrate how many lines are displayed with the first two words, if both are used, the password is implemented. Where the code is as follows:
[UIHint ("Multilinetext")] [DataType (Datatype.password)] public bool isapproved {get; set;} @model bool<select id= "role" name= "role" > <option value= "@Model" @ (model = = true?) "Selected=\" selected\ "": "") > Notifications </option> <option value= "@ (! Model) "@ (model = = False?) "Selected=\" selected\ "": "") > Not notified </option></select>
Can be deleted by itself to observe the effect. In addition to the above situation, there may be other circumstances, the specific encounter and then to study.
Iii. Understanding Metadata Delivery systemAs of now, we have looked at some of the previous examples, what in our above example for our silent service? There are meta-data mentioned earlier, so who created the metadata? The answer is the Dataannotationsmodelmetadataprovider class. It is to examine and process the attributes that precede our load class, and then render it in view according to its characteristics. You can use F12 to see its definition, it will find that it is inherited associatedmetadataprovider an abstract class, Then we can understand that: Associatedmetadataprovider provides some methods for the use of metadata, such as creating a metadata method, and then the Dataannotationsmodelmetadataprovider class overrides his method, Finally, some attributes, or attributes, belong to the metadata. A few bends around, or the use of a picture of old a better description:
Look at this picture, the more exciting children's shoes would like to create a custommodelmetadataprovider inherit Associatedmetadataprovider class, then let us try to rewrite the Createmetadata method, Let me take my isapproved as an example, because the translation is a bit inappropriate, I would like to change him to agree.
Create a folder under the project, and then add a class
The code is as follows:
public class Custommodelmetadataprovider:associatedmetadataprovider {protected override Modelmetadata C Reatemetadata (ienumerable<attribute> attributes, Type Containertype, Func<object> modelaccessor, Type Modeltype, String propertyname) {//modelmetadata metadata = base. Createmetadata (attributes, Containertype, Modelaccessor,//modeltype, PropertyName); Modelmetadata metadata =new Modelmetadata (this, Containertype, Modelaccessor, Modeltype, PropertyName); if (propertyname! = null && propertyname.equals ("isapproved")) {metadata. DisplayName = "assent"; } return metadata; } }
Finally add the initialization code in the global File Application_Start ():
Modelmetadataproviders.current = new Custommodelmetadataprovider ();
found that the displayed lable has been changed, but the other added metadata does not work. If you want it to work, you must inherit Dataannotationsmodelmetadataprovider, then implement the parent class method, and finally add your own functionality so that you can see the effect we want. The code is as follows:
protected override Modelmetadata Createmetadata ( ienumerable<attribute> attributes, Type Containertype, func<object> modelaccessor, Type modeltype, string propertyname) { Modelmetadata metadata = base. Createmetadata (attributes, Containertype, Modelaccessor, Modeltype, PropertyName); Modelmetadata metadata =new Modelmetadata (this, Containertype, Modelaccessor, //modeltype, PropertyName); if (propertyname! = null && propertyname.equals ("isapproved")) { metadata. DisplayName = "assent"; } return metadata; }
Running time, we can set breakpoints at the time of creating metadata to see the meanings of each parameter to better understand the class and method. Ready to finish, other methods will not be implemented here.
Iv. Summary:Through a simple example, this paper introduces the template helper, then realizes the custom template, and finally explains the principle of the Model template implementation. There may be some nouns called is not very accurate, on the one hand because their e-text is not good, another aspect is to better understand, if there is insufficient place please Daniel many guidance. Enclose the code in the article: source. The code is written using VS2010.
V. Reference documents:1. "Pro ASP. MVC3 Framework"
2, http://home.cnblogs.com/u/mszhangxuefei/
3, http://www.cnblogs.com/artech/
One of the ASP. Mvc--model Model Templates