In the previous article, we introduced the basic usage of Automatic Binding. In this article, we will have a deep understanding of the working principle of automatic binding.
Automatic Binding is indeed an exciting feature. However, to make it work better in our project, it is necessary to have a deep understanding of how to further tune this feature and how it works. this article is about to reveal the answer.
To better understand this feature, we need to download a copy of The Asp.net MVCSource codeAt the time of writing this article, codeplex has installed the beta version of the source code. If you want to know more about it, you can download it and analyze it against this article.
In beta, automatic binding is added, and some modifications are made to the binding feature.
1.New bindattribute: automatically bound feature settings
2.Modify defamodelmodelbinder: Implementation of Automatic Binding
3.Modify controlleractioninvoker: bound call entry
4.Added modelbindercontext to encapsulate the data required for binding.
5.Binderresult is added to encapsulate the binding result.
Other minor changes are skipped
We analyze the binding execution process step by step. First, we must see the getparametervalue method in controlleractioninvoker:
Here, we try to call modelbinder to bind parameters for each parameter. The getmodelbinder method here is the same as that of P5. In the case of custom modelbinder, we can perform custom binding, however, defamodelmodelbinder is obtained during Automatic Binding. Then, in the getpropertyfilter method, you can view bindattrider to obtain binding settings. finally, bind the data.
The key is that we need to analyze defamodelmodelbinder. However, before that, we need to take a closer look at another class, namely, bindattribute, which is used to modify parameters, it has four important attributes: Include, exclude, prefix, and Method: ispropertyallowed, which are used to set: bound fields, unbound fields, respectively, the parameter prefix is used to determine whether the specified field is set to run binding. This method is used as a predicate delegate to block modelbindercontext and pass in the bindmodel method.
Now we will discuss the use of default binding. First, we will provide all the defaultmodelbinder methods:
The roles of these methods are described as follows:
1.Bindmodel:The external call interface is bound according to the passed modelbindercontext value.
2.Bindmodelcore:Bind custom type, custom type array or custom type dictionary
3.Bindproperty:Binds a specified attribute. (This is a recursive call. defamodelmodelbinder is still called to binder the attribute. That is to say, in theory, defamodelmodelbinder can bind any in-depth attribute)
4.Convertsimplearraytype, convertsimpletype,Used for type conversion. One conversion array and one conversion normal type
5.Createarray:Create an array object
6.Createmodel:Create a Common Object
7.Createsubindexname:Create a sub-index name named by prefix [indexname]
8.Createsubpropertyname:Create a sub-attribute name named by prefix. propertyname
9.Getbinder:Get the binder object of modeltype
10.Getelementtype:Obtain an elementtype
11.Getsimetype:Binds a simple value to a given modelbindercontext (that is, when this method is called, it is assumed that the obtained data is of a simple type)
12.Iscollectioninserface:Determine whether it is an array type
13.Isdictinaryinterface:Determine whether it is a dictionary type
14.Issimpletype:Whether it is a simple type (check whether it is a value type or a string here)
15.Tryupdatesimplecollection:Try to bind a simple array (that is, bind collection or collection, and t can use issimpletype)
16.Updatecollection:Binds an array. This array is generally set to collection and T is a custom type.
17.Updatedictionary:Bind a dictionary type
Through the above method, we found that defaultmodelbinder can bind a lot of data, including simple type (Value Type and string ). custom types, arrays, and dictionaries. Due to recursive calls, data in any depth can be bound theoretically. Due to the complexity of the calls bound here, I have limited ability to express myself, this article will not detail the binding workflow. The binding rules will be summarized below:
1.By default, data is bound to the desired object through reflection.
2.The bindattribute parameter has an optional attribute.
3.BindattributeYou can manually set attributes that can be bound or attributes that cannot be bound. The URL takes the parameter prefix.
4.All attributes are bound by default.
5.DefaultmodelbinderRecursively bind all parameters to be bound
6.The naming method of common parameters is: prefix. protertyname. By default, the prefix is the type name. if the object mydata has the property name of string type, the value in valueprovider should be mydata. name, case-insensitive
7.The simple array naming method is prefix. protertyname, where proertyname is the array name and multiple
8.For custom arrays and dictionaries, the following parameters must be provided for binding:
1.Index-One or more sub-element names must be provided to indicate the bound sub-element names. multiple sub-element names can exist.
2.The array must provide one or more entries using protertyname [indexname]. subprotertyname indicates the form data ending in the form of subprotertyname, where protertyname indicates the array name, indexname indicates the name defined in index, and subproteryname indicates the property name of the custom type.
3.The dictionary must provide one or more protertyname [indexname]. key and protertyname [indexname]. value form data, where protertyname is the dictionary name, indexname is the name defined in index, key represents the key binding in the dictionary, value represents the value binding in the dictionary, if the key or value type is not simple, continue to refer to the previous section for the form definition.
9.For the above binding, if the child-level attribute is of a complex type, you can name the form data according to this rule in sequence.
The preceding rules are described in the following example:
In the experience section, we can see that the form for article is named article. title, article. content and so on. This is based on the 6th entries. The parent class and attribute are used. to separate, name simple data, article. tags. Multiple tables with the same name represent multiple family elements. For more information, see section 7th. Here, if the prefix is explicitly defined in the Article parameter, You need to modify the table single name accordingly. if the property is of the custom type, continue to use it. interval, for example, article. advancearticle. today. For more information, see article 7 and article 9. For examples of these parts, see article 1.
This article will focus on custom type arrays, dictionaries, and multi-level attribute binding. The following shows how to bind an icollection, T is a custom type. For example, add an attribute reads in advancearticle, this is a custom type, including name and source, instanceCodeAs follows;
Then add the following content to form aspx according to the rule:
Two elements are introduced to this array, corresponding to article. reads. 0 and AA in index, and the following article. reads [0]. name and article. reads [0]. source indicates the sub-attributes of the first element, and so on. if you need to add more elements to the array in the application, you can use js to dynamically add form fields. However, each addition must correspond to an index and a subattribute form.
Then bind dictinary. We will add the new attribute in advancearticle:
Then add the form to aspx:
Similar to arrays, You need to define article. source. index, which explicitly defines two dictionary elements: user and VIP (note that the user and VIP here do not represent the dictionary key, and the dictionary key needs to be bound from the form ), then define article. source [user]. key and article. source [user]. key. if more elements exist, add them according to this rule.
Similarly, the key and value here are not limited to simple types. If the key and value are custom types, you can continue to define them according to the previous rules.
Note the following points: By Leven
2008-10-22
1.The binding value is not limited to form fields. valueprovider is added to Beta, and can be bound to any value that can be obtained in valueprovider.
2. automatic binding is based on reflection. If you think the efficiency is not high enough, please use the custom modelbinder method to bind a specific type, which has improved efficiency
3.Automatic Binding is one-way. If you want to accept this parameter in route, you can rewrite the tostring method of the bound object to output the corresponding querystring method, that is, if you want to call the URL. action ("XXX", new {Article = myarticle}) can pass in outgoing parameters correctly. You can override the tostring method of article and provide a method similar to article. title = xxx & article. the string format of content = xxx provides a help class to put the data into valueprovider separately, while the URL method is called using a URL similar. action ("XXX", article. toroutevalue () method.
By Leven
2008-10-22