ASP. net mvc Model binding (4)

Source: Internet
Author: User

ASP. net mvc Model binding (4)Preface

The previous sections gave a rough explanation of the Model binder IModelBinder, implementation type, and Model binder provider. we can think of the Model binder as a large container. Why? Leave a question here.

First, the Controller's method parameters may be of many types and may be of the same type. In this case, the binding implementation used by the MVC framework is implemented by IValueProvider, for different parameter types, the implementation types of IValueProvider are also very different. The specific implementation will be explained in the subsequent sections.

We should not go into the MVC Framework and stand out. This article describes IValueProvider from an external perspective.

 

Model Bind
  • IModelBinder, Custom ModelSimple implementation of the binder
  • ModelThe binder is in the MVCPosition in the framework
  • MVCDefault Model inBinding Process
  • IModelBinderProviderSimple Application
  • IValueProviderIn MVCPosition and process generated in the framework
  • IValueProviderApplication scenarios
  • IValueProviderNameValueCollectionValueProvider

 

Position and process of IValueProvider generated in the MVC Framework

Generated location

Can you remember the description of the location where the Model binder is generated in ASP. net mvc Model binding (2)? Here I will use the description of the location where the Model binder is generated,

Figure 1

As shown in figure 1, after the Model binder is generated, the IValueProvider type is generated in the Blue Line execution process. If it is said that the generation is incorrect, change it to get it. Why do we talk about this in the following generation section?

 

Generation Process

Let's first look at the implementation code of the Blue Line Flow in section 1.

Code 1-1

protected virtual object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)        {            Type parameterType = parameterDescriptor.ParameterType;            IModelBinder modelBinder = this.GetModelBinder(parameterDescriptor);            IValueProvider valueProvider = controllerContext.Controller.ValueProvider;            string str = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName;            Predicate<string> propertyFilter = GetPropertyFilter(parameterDescriptor);            ModelBindingContext context2 = new ModelBindingContext            {                FallbackToEmptyPrefix = parameterDescriptor.BindingInfo.Prefix == null,                ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, parameterType),                ModelName = str,                ModelState = controllerContext.Controller.ViewData.ModelState,                PropertyFilter = propertyFilter,                ValueProvider = valueProvider            };            ModelBindingContext bindingContext = context2;            return (modelBinder.BindModel(controllerContext, bindingContext) ?? parameterDescriptor.DefaultValue);        }

For the method shown in code 1-1, we don't need to worry about its return type and the role of this method. What we want to know now is how IValueProvider comes from !!!

From code 1-1, we can clearly see that after the Model binder is generated, the MVC Framework obtains the reference of the Controller requested by the current request from the context parameter object of the ControllerContext controller, then, the IValueProvider type is obtained based on the reference of the current controller object.

Then, the MVC Framework instantiates the ModelBindingContext type and assigns the obtained IValueProvider type to the ValueProvider attribute.

For the ModelBindingContext type, Model binds the context object and you can see its definition code 1-2.

Code 1-2

Public class ModelBindingContext {public ModelBindingContext (); public ModelBindingContext (ModelBindingContext bindingContext); public bool FallbackToEmptyPrefix {get; set;} public object Model {get; set;} public ModelMetadata {get; set;} public string ModelName {get; set;} public ModelStateDictionary ModelState {get; set;} public Type ModelType {get; set;} public Predica Te <string> PropertyFilter {get; set;} public IDictionary <string, ModelMetadata> PropertyMetadata {get ;}/// Summary: // gets or sets the value provider. //// Return result: // value provider. Public IValueProvider ValueProvider {get; set ;}}

Here, we only need to get a preliminary understanding of the ModelBindingContext type, and return to the topic. As mentioned above, we can get it directly from the reference of the current controller object, so let's take a look at the ValueProvider attribute in the controller. Let's take a look at the Controller type, code 1-3.

Code 1-3

public abstract class Controller : ControllerBase, IActionFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter{   ……}

I made a joke to ease the atmosphere. The Controller type does not have the attribute we are looking for. Some friends think that it is in the base class type, and it is indeed in the ControllerBase type (code 1-4 ).

Code 1-4

public abstract class ControllerBase : IController{   ……   public IValueProvider ValueProvider { get; set; }}

Do we need to assign a value to the Controller object when using IValueProvider?

Of course not. Let's take a look at the implementation of the ValueProvider attribute in code 1-4, sample code 1-5.

Code 1-5

public IValueProvider ValueProvider        {            get            {                if (this._valueProvider == null)                {                    this._valueProvider = ValueProviderFactories.Factories.GetValueProvider(this.ControllerContext);                }                return this._valueProvider;            }            set            {                this._valueProvider = value;            }        }

We should have understood the origins of the IValueProvider type, which is obtained from the ValueProviderFactories attribute of the system based on the context of the current controller.

Here we will take a look at several definitions of related types of the IValueProvider type. The sample code is 1-6.

Code 1-6

Public static class ValueProviderFactories {// Summary: // gets the set of value providers of an application factory. //// Return result: // a set of value provider factory objects. Public static ValueProviderFactoryCollection Factories {get ;}}
Public class ValueProviderFactoryCollection: Collection <ValueProviderFactory> {public ValueProviderFactoryCollection (); public ValueProviderFactoryCollection (IList <ValueProviderFactory> list); // Summary: // provides a program factory for the context return value of the specified. //// Parameter: // controllerContext: // an object that encapsulates information about the current HTTP request. //// Return result: // It is used to specify the value of the controller context to provide the program factory object. Public IValueProvider GetValueProvider (ControllerContext controllerContext); protected override void InsertItem (int index, ValueProviderFactory item); protected override void SetItem (int index, ValueProviderFactory item );} public abstract class ValueProviderFactory {protected ValueProviderFactory (); // abstract: // provides a program object for the context return value of the specified controller. //// Parameter: // controllerContext: // an object that encapsulates information about the current HTTP request. //// Return result: // value provider object. Public abstract IValueProvider GetValueProvider (ControllerContext controllerContext );}

ValueProviderFactories is a set type of valueproviderycollection, which contains static properties of the ValueProviderFactoryCollection type. The ValueProviderFactoryCollection type is a set type of the ValueProviderFactory type, therefore, when the IValueProvider type is finally generated, the ValueProviderFactoryCollection type is first traversed to obtain the instances of each ValueProviderFactory type and generate the IValueProvider type. Here the first match is not the best match.

Here refer to the following example: You can use the Controller context object to classify the generation logic of the ValueProviderFactory type and generate different IValueProvider types for different controllers. The use of the IValueProvider type will be described later.

 

 

Author: Jin Yuan

Source: http://www.cnblogs.com/jin-yuan/

The copyright of this article is shared by the author and the blog Park. You are welcome to reprint this article. However, you must keep this statement without the author's consent and go to the Article Page.

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.