Simulate the model binding mechanism of ASP.net MVC by example: array

Source: Internet
Author: User
Tags foreach object model

[Continuation of the model binding mechanism through example simulation asp.net MVC: Simple type + complex Type]] The model binding mechanism based on array and collection type is similar to that for a binding parameter type or a property of a parameter type that is an array or collection. If Valueprovider can match more than one piece of data based on the corresponding key, the data will eventually be converted to the elements of the bound array/collection. In addition, the model bindings for arrays/collections also support an indexed approach. [Source code download from here]

One, name-based array binding

For Namevalueconllectionprovider, the rawvalue of the Valueproviderresult obtained by the GetValue method is always an array of strings (whether or not there is more than one piece of data matching the specified key). If there is only one matching piece of data, RawValue is an array of strings with one element. When we call the Valueproviderresult ConvertTo method to convert the supplied value to a type, if the target type is an array or a collection, then the string array elements represented by RawValue will be converted to the elements of the target object, and if the target type does not belong to the collection, The only 1th element in the RawValue array is the participant in the Data transformation.

As shown in the following code snippet, in the default HomeController action method index, we create a Namevaluecollectionvalueprovider object, The NameValueCollection as a data source contains three entries of the same name (foo). We call its GetValue method to get a Valueproviderresult object, and then we present the object's RawValue. Finally, we call the Valueproviderresult object's ConvertTo object to convert the supplied value to int[] and int, and render the converted value.

 1:public class Homecontroller:controller 
2: {
3:public void Index ()
4: {
5: NameValueCollection DataSource = new NameValueCollection ();
6:datasource.add ("foo", "123");
7:datasource.add ("foo", "456");
8:datasource.add ("foo", "789");
9:namevaluecollectionvalueprovider valueprovider = new Namevaluecollectionvalueprovider (DataSource, Cultur Einfo.invariantculture);
10: 
11:valueproviderresult result = Valueprovider.getvalue ("foo");
12:response.write (String. Format ("RawValue: {0}<br/>", result. RawValue));
13:response.write (String. Format ("ConvertTo (typeof (Int[)): {0}<br/>", result. ConvertTo (typeof (Int[])));
14:response.write (String. Format ("ConvertTo (typeof (int)): {0}<br/>", result. ConvertTo (typeof (int)));
15:}
:}

After running this program, we will get the following output in the browser, which can be verified from the output of the Namevalueconllectionprovider.

   1:rawvalue:system.string[]
2:convertto (typeof (Int[)): system.int32[]
3:convertto (typeof (int)): 123

The data value provider for Namevalueconllectionprovider (Formvalueprovider and Querystringvalueprovider) determines the default behavior of model bindings. If the target object of the binding is an array or collection, matching data items of the same name will be the elements of the target object. In fact, the Httpfilecollectionvalueprovider data value provides the same mechanism, and if the bound target object type is a httppostedfilebase array, matching file input elements of the same name will be used as their data source.

   1: <input name= "Foo" type= "text" .../>
2: <input name= "Foo" type= "text" .../>
3: <input name= "Foo" type= "text" .../>
4: <input name= "Bar" type= "file" .../>
5: <input name= "Bar" type= "file" .../>
6: <input name= "Bar" type= "file" .../>

Suppose that the Actionmethod submitted for the action method with the following definition has the INPUT element as above, the string entered in the three text boxes will be bound to the Foo parameter, and the file uploaded through three file input elements will be bound to the bar parameter.

   1:public void Actionmethod (string[] foo, httppostedfilebase[] bar)

Now we further refine the custom defaultmodelbinder used to simulate the default model bindings to provide support for array-based array bindings. As shown in the following code snippet, we added the model binding code for the array type in the Bindmodel method, and the specific implementation is defined in the Bindarraymodel method.

1:public class Defaultmodelbinder
2: {
3://other Members
4:public Object Bindmodel (Type parametertype, string prefix)
5: {
6:if (!this. Valueprovider.containsprefix (prefix))
7: {
8:return null;
9:}
10:
11:modelmetadata Modelmetadata = ModelMetadataProviders.Current.GetMetadataForType (() => null, parametertype);
12:if (!modelmetadata.iscomplextype)
13: {
14:return this. Valueprovider.getvalue (prefix). ConvertTo (ParameterType);
15:}
16:if (Parametertype.isarray)
17: {
18:return Bindarraymodel (parametertype, prefix);
19:}
20:object model = Createmodel (parametertype);
21st:
22:foreach (PropertyDescriptor property in Typedescriptor.getproperties (ParameterType))
23: {
24:string key = string. IsNullOrEmpty (prefix)? Property. Name:prefix + "." + property. Name;
25:property. SetValue (model, Bindmodel (property). PropertyType, key));
26:}
27:return model;
28:}
29:private Object Bindarraymodel (Type parametertype, string prefix)
30: {
31:ilist list = new list<object> ();
32:if (this. Valueprovider.containsprefix (prefix))
33: {
34:ienumerable enumerable = this. Valueprovider.getvalue (prefix). ConvertTo (ParameterType) as IEnumerable;
35:if (null!= enumerable)
36: {
37:foreach (var value in enumerable)
38: {
39:list. ADD (value);
40:}
41:}
42:}
43:array Array = array.createinstance (Parametertype.getelementtype (), list. Count);
44:list. CopyTo (array,0);
45:return Array;
46:}
47:}

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.