Thomas
Thomas

Reputation: 34218

ASP.Net MVC: What’s the Difference Between a Value Provider and Model Binder

I was reading a write up on What’s the Difference Between a Value Provider and Model Binder.

I understand that Model Binder basically get incoming data and build object. Suppose I am sending student data then model binder grab incoming student data when from post to server and build student object.

But still do not understand what is the job of Value Provider in MVC.

So please explain with easy sample that what kind of job done by Value Provider and what model binder does?

this is not clear what haacked.com is saying

The DefaultModelBinder will pull the Id value from the RouteData and the Age, FirstName, and LastName values from the JSON when building up the Person object. Afterwards, it’ll perform validation without having to know that the various values came from different sources.

When i am posting id,name,age etc then why model binder will pick id only from route data and rest of data from JSON. model binder should pick all value from RouteData or all value from JSON..............so why id only ?

How many different type of value provider exist in mvc ?

Upvotes: 7

Views: 6650

Answers (3)

Kiran
Kiran

Reputation: 57999

Model binder (for example, like the one binding to complex type) have the responsibility of going through the type graph (i.e recursively looking for bindable properties) and trying to find values for these properties. The binder gets these values from the value providers.

Just imagine if you were to write your own model binder similar to the complex type binder. It is non-trivial code. So one should carefully decide if they want to write a value provider or a model binder. You could think like "If I create a valueprovider, then I get all the recursive binding of properties for free".

Upvotes: 0

Emmanuel DURIN
Emmanuel DURIN

Reputation: 4913

ValueProviders are for getting data from different sources in the request

ModelBinders take the data from the ValueProviders to create an object. They don't directly take it from Route Data, or JSON or some specific, it's not their responsibility.

  • List of available ValueProviders in ASP.Net MVC 5, by priority order :

    1. ChildActionValueProviderFactory
    2. FormValueProviderFactory
    3. JsonValueProviderFactory
    4. RouteDataValueProviderFactory
    5. QueryStringValueProviderFactory
    6. HttpFileCollectionValueProviderFactor
  • List of available ValueProviders in ASP.Net Web API, by priority order :

    1. QueryStringValueProviderFactory
    2. RouteDataValueProviderFactory

Reference : Brad Wilson in Professional ASP.Net MVC 5, Wrox edition

Multiple ValueProviders can cooperate to get data from different sources.

Priority matters if data is provided multiple times.

e.g. : id comes from querystring and RouteData - RouteData wins over querystring

All the best

Upvotes: 8

dotnetstep
dotnetstep

Reputation: 17485

I may be too late to answer but I hope this might useful to community.

First point related to link : Value Provider and Model Binder.

  1. ValueProvider : ValueProvider in mvc is like parsed source of dictionary that help modelbinder to get appropriate value for its model. if you look at interface IValueProvider , It has two method. ContainPrefix and GetValue. ContainPrefix is help you to identify child model. For example Person Model insider Customer. Like that.

    • If you look at DefaultModelBinder It will get bind value if you specify in Query string or Form or RouteData. Behind the scene ValueProvider comes at help. ModelBinder it self does not know. ValueProvider one layer below ModelBinder.
  2. There are many type of ValueProvider is MVC. Even you can build your own value provider and register with MVC Framework in Global.asax.

    In Application_Start of Global.asax

     protected void Application_Start()
        {
            // Other default configuration
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            var valueProviders = ValueProviderFactories.Factories;     // To Get List of ValueProviders. This list order is also important.       
        }
    
  3. If you look at actual link Peoson json object it does not have Id Value so it will take value RouteData. If your Person json object contain Id value that there are two source of Id Value. Now whichever value provider comes first get priority. ( List of ValueProvider). If JsonValueProvider comes first then it will take priority bind Id value and if RouteDataValueProvider comes first then it will get priority bind Id value.

    To See this you can try like this in global.asax application_start. ( In my list JsonValueProvider comes first so I removed that and Add at Last)

    protected void Application_Start()
    {
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    var valueProviders = ValueProviderFactories.Factories;
    ValueProviderFactories.Factories.RemoveAt(2); // My JsonValueProvider was at index 2.
    ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
    }
    

Upvotes: 1

Related Questions