The core of the ModelBinder:ASP.NET MVC model binding

Source: Internet
Author: User
Tags abstract definition visual studio

The model's bindings are reflected in the parameters that extract the appropriate data from the current request to the target action method. We know from the previous introduction that the parameters of the action method are described by Parameterdescriptor, The Parameterbindinginfo object represented by the Parameterdescriptor Bindinginfo property has a component named Modelbinder that completes the model binding for the current parameter. Modelbinder can be seen as the core of the entire model binding system, and we first recognize this important component.

First, Modelbinder

The Modelbinder object used for model binding implements the interface Imodelbinder. As the following code fragment shows, the Imodelbinder interface has a unique Bindmodel method to implement a binding operation on a parameter that represents the object that is ultimately the parameter value.

   1:public Interface Imodelbinder
2: {
3: object Bindmodel (ControllerContext controllercontext, Modelbindingcontext BindingContext);
4:}

The Imodelbinder Bindmodel method accepts two parameters, one representing the current controller context, and the other representing the context for the current model binding, expressed by type Modelbindingcontext. The controller context was created when the controller was initialized, so as long as we were able to create the corresponding modelbindingcontext for the current model binding, We can use Modelbinder based on a parameter to get the corresponding parameter value. About the creation of Modelbindingcontext we will be in the next part of the separate introduction, we first introduce the modelbinder of the delivery mechanism.

Ii. Custommodelbinderattribute and Modelbinderattribute

If the parameterdescriptor for a parameter has a corresponding Modelbinder, it is selected for the model binding for that parameter. So how does Parameterdescriptor's modelbinder come to be delivered? This is actually setting a Custommodelbinderattribute attribute with the following definition. Abstract class Custommodelbinderattribute defines a unique abstract method Getbinder used to get the corresponding Modelbinder object.

   1: [AttributeUsage (Attributetargets.parameter | Attributetargets.interface | Attributetargets.enum | Attributetargets.struct
2: | AttributeTargets.Class, Allowmultiple=false, Inherited=false)]
3:public Abstract class Custommodelbinderattribute:attribute
4: {
5: Public abstract Imodelbinder getbinder ();
6:}

In the ASP.net MVC application Programming interface, Custommodelbinderattribute has a unique inherited type Modelbinderattribute with the following definitions. We can dynamically select the type of modelbinder used for model bindings by applying the Modelbinderattribute feature.

   1: [AttributeUsage (Attributetargets.parameter | Attributetargets.interface |
2: Attributetargets.enum | attributetargets.struct | AttributeTargets.Class,
3: Allowmultiple=false, Inherited=false)]
4:public Sealed class Modelbinderattribute:custommodelbinderattribute
5: {
6: Public Modelbinderattribute (Type bindertype);
7: Public override Imodelbinder Getbinder ();
8:
9: Public Type Bindertype {[compilergenerated] get; }
10:}

From the AttributeUsageAttribute definition applied to the Modelbinderattribute type, you can see that the attribute can be applied not only to parameters, but also to types (interfaces, enumerations, structs, and classes). This means that we can either apply it to an argument on the action method or apply it to the type of a parameter. However, parameterdescriptor only resolves the attributes applied to the parameter, so the Modelbinderattribute applied on the Parameter object type is not valid for it.

To demonstrate the impact of the Modelbinderattribute feature on Parameterdescriptor, let's take a simple example demo. Several types are defined in an empty Web application created through the ASP.net MVC project template in Visual Studio. Where Foomodelbinder and Barmodelbinder are custom modelbinder types that show Imodelbinder, and Foo, bar, and Baz are three data types that will be parameters to the action method. The Modelbinderattribute attribute is applied on bar and the Modelbinder type is set to Barmodelbinder.

   1:public class Foomodelbinder:imodelbinder
2: {
3: Public object Bindmodel (ControllerContext controllercontext, Modelbindingcontext BindingContext)
4: {
5: throw new NotImplementedException ();
6: }
7:}
8:public class Barmodelbinder:imodelbinder
9: {
All: Public object Bindmodel (ControllerContext controllercontext, Modelbindingcontext BindingContext)
One: {
A: throw new NotImplementedException ();
: }
14:}
15:
16:public class Foo {}
[Modelbinder (typeof (Barmodelbinder))]
18:public class Bar {}
19:public class Baz {}

The following two action methods are defined in the default HomeController that are then created. The DoSomething method has three parameters, the types are Foo, bar, and Baz, the Modelbinderattribute attribute is applied on the first parameter, and the Modelbinder type is set to Foomodelbinder.

1:public class Homecontroller:controller
2: {
3:public void Index ()
4: {
5:controllerdescriptor controllerdescriptor = new Reflectedcontrollerdescriptor (typeof (HomeController));
6:actiondescriptor actiondescriptor = controllerdescriptor.findaction (ControllerContext, "DoSomething");
7:imodelbinder foo = actiondescriptor.getparameters (). A (p => p.parametername = = "Foo"). Bindinginfo.binder;
8:imodelbinder bar = Actiondescriptor.getparameters (). A (p => p.parametername = = "Bar"). Bindinginfo.binder;
9:imodelbinder baz = Actiondescriptor.getparameters (). A (p => p.parametername = = "Baz"). Bindinginfo.binder;
10:
11:response.write (String. Format ("foo: {0}<br/>", null = = Foo?) "N/a": Foo. GetType (). Name));
12:response.write (String. Format ("Bar: {0}<br/>", null = = bar?) "N/a": bar. GetType (). Name));
13:response.write (String. Format ("Baz: {0}<br/>", null = = Baz?) "N/a": Baz. GetType (). Name));
14:}
15:
16:public void DoSomething ([Modelbinder (typeof (Foomodelbinder))]foo Foo,bar Bar, bar Baz)
17: {}
18:}

In the default action method index, We target the Reflectedcontrollerdescriptor object of the HomeController type and get the Actiondescriptor object that describes the action method dosomething. Finally, we obtain the Parameterdescriptor object for describing its three parameters through the Actiondescriptor object and present its modelbinder in the west. When we run the program, we will produce the following output in the browser, which can be seen for the modelbinderattribute characteristics applied to the parameters and parameter types, respectively. Only the former will affect the choice of parameterdescriptor Modelbinder.

   1:foo:foomodelbinder
2:bar:n/a
3:baz:n/a

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.