Friday 22 July 2016

Custom Value Provider in MVC

Value providers are components which provides data to model binders. MVC has some default value providers which feed data to model binders.

1.  FormValueProvider  : Fetch data from Request.Form and pass to model binders.

2. RouteDataValueProvider : Fetch data from RouteData.Values

3. QueryStringValueProvider : Fetch data from Request.QueryString

4. HttpFileCollectionValueProvider : Fetch data from Request.Files.

Model binders search data from value providers and bind to the model. Given value providers are default in MVC but you can also create your custom value provider depends on your requirement.  I have wrote small code to create custom value provider.

Create Value provider class :
using System.Web.Mvc;
public class CustomValueProvider : IValueProvider
{
        public bool ContainsPrefix(string key)
        {
            // Do logic as per requirement. e.g here we are cheking for cookie with given  key
            return HttpContext.Current.Request.Cookies[key] != null;
        }

        public ValueProviderResult GetValue(string key)
        {
            // if ContainsPrefix == true then this method called which return actual value of key.
            return new ValueProviderResult(HttpContext.Current.Request.Cookies[key].Value,
                                                                 HttpContext.Current.Request.Cookies[key].Value, 
                                                                 CultureInfo.CurrentCulture);
        }
}

Create Factory to register value provider :

 // Create Factory for your Value provider
    public class MyCustomValueFactory : ValueProviderFactory
    {
        public override IValueProvider GetValueProvider(ControllerContext controllerContext)
        {
            // Register custom value provider
            return new CustomValueProvider();
         }
    }

And last step, Add factory to value providers factories in Application_Start event in global.asax

public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {            
            // Register custom value provider factory
            ValueProviderFactories.Factories.Add(new MyCustomValueFactory());
        }
}

Your custom value provider is ready. Now let’s use it in real code.
 public ActionResult Index()
 {
     Response.Cookies.Add(new HttpCookie("ajay""Ajay Patel"));
     return View();
 }

[HttpPost]
public JsonResult TestPostMethod(string ajay)
{
     return Json("Hey I got value :)");
}

Model binders search “ajay” in default values providers if not found from default providers  then search in custom value providers. If model binder found value of “ajay” then it will stop search further for same parameter and search for next parameter if any.

That’s All.