Wednesday, September 10, 2014

Custom Value Providers in ASP.Net MVC

This article describes Custom Value Providers in MVC and their uses. Value Providers are the components that feed data to model binders. Feeding the data means installing the data to the Model binder for further use at the action level.
The framework contains a few built-in value providers named FormValueProvider, RouteDataValueProvider, QueryStringValueProvider and HttpFileCollectionValueProvider that fetch data from Request.Form, Request.QueryString, Request.Files and RouteData.Values.

These Value Providers are called in the order they are registered and so the one that is registered earlier gets the first chance. We can easily restrict the model from binding with the data from a specific Value Provider.
In this article we will see how to create custom value providers that fetch a value from a cookie and pass model binders at the action level.
Down the level, I have created a controller that has an action declared as an index. When the Index action is called using GET a cookie is added to the browser called "Id" with the value "E001" assigned to it.
When the form is posted [HttpPost] an index action is again called and the cookie value is automatically assigned to the Id parameter on the POST index method. But how?

Each value provider implements an interface IValueProvider that has two methods as shown below in the image:
value provider implements
The ContainsPrefix method is called by the model binder to determine whether the value provider has the data for a given prefix. The GetValue method returns a value for a given data key or returns null if the provider doesn't have any suitable data. Here is an implementation of both methods as shown below in the image:

In the image shown above the ContainsPrefix method checks whether the passed parameter is stored in the cookie (or the value the user has registered in another request/response parameters) and returns true or false. In the GetValue method it returns a value from the cookie collection for the passed key (in our case it's Id).

Now it's time to register the value provider through factories to make them install data to the model binder. We need to create a factory to register our CustomValueProvider by deriving from the abstract class ValueProviderFactory. The factory contains a single method GetValueProvider where we should instantiate our custom value proivder and return it.


Now we need to register CustomValueProviderFactory to the ValueProviderFactories.Factories collection in the Application_Start event of Global.asax.cs as shown in the following image:

Now I press F5 and run the application.
run the application
Let's run the application and discuss the points step-by-step to fetch the value from the CustomValueProvider.
Step 1: As soon as it runs the application it registers a cookie value as depicted in the image below:

cookie value

Step 2:
Fill in the required values and press the ok button, kindly see the following image:

Fill the required values

Step 3: It calls the CustomValueProvideFactory class to instantiate CustomValueProvider as depicted in the image below:


Step 4: At the time of the model binding the DefaultModelBinder checks with the value providers do determine if they can return a value for the parameter Id by calling the ContainsPrefix method. If none of the value providers registered can return then it checks through CustomValueProvider whether such a parameter is stored and if yes it returns the value. Kindly refer to the screen shot given below:

parameter Value

Step 5: A final step is at the post action method when it retrieves a cookie value from CustomValueProvides.

post action method

Important Note: If we change the parameter exists in action method then it doesn't find a value from the registered custom value provider due to a mismatch and it returns null. You can also retrieve multiple values from value providers. Kindly find the attached sample application.

Kindly refer to the image below:

sample application
The Value Providers Magic is Over.

I hope you enjoyed this and that it may help you down the line.

To learn more about MVC please go to the following link.

MVC Articles
Enjoy Coding and ReadingSmile


Post a Comment