Custom model binding system

Source: Internet
Author: User

1. Create a custom value provider

1. By creating a custom value provider, we can add our own data sources to the model binding process. The value provider must implement the ivalueprovider interface. The following is the definition of this interface

namespace System.Web.Mvc{    /// <summary>    /// Defines the methods that are required for a value provider in ASP.NET MVC.    /// </summary>    public interface IValueProvider    {        /// <summary>        /// Determines whether the collection contains the specified prefix.        /// </summary>        /// <param name="prefix">The prefix to search for.</param>        /// <returns>true if the collection contains the specified prefix; otherwise, false.</returns>        bool ContainsPrefix(string prefix);        /// <summary>        /// Retrieves a value object using the specified key.        /// </summary>        /// <param name="key">The key of the value object to retrieve.</param>        /// <returns>The value object for the specified key. If the exact key is not found, null.</returns>        ValueProviderResult GetValue(string key);    }}

The containsprefix method is called by the model binder to determine whether the value provider can parse the given pre-data.

The getvalue method returns the value of the given data key, or returns "null" if the value provider cannot obtain the appropriate data ".

We define a custom value provider.

using System;using System.Collections.Generic;using System.Globalization;using System.Linq;using System.Web;using System.Web.Mvc;namespace WebApplication4.Models{    public class CurrentTimeValueProvider : IValueProvider    {        public bool ContainsPrefix(string prefix)        {            return string.Compare("CurrentTime", prefix, true) == 0;        }        public ValueProviderResult GetValue(string key)        {            return ContainsPrefix(key) ? new ValueProviderResult(DateTime.Now, null, CultureInfo.InvariantCulture) : null;        }    }}

 

2. How to register the custom value provider to the application. We need to create a factory class to create a value provider instance. This class is derived from the abstract class valueproviderfactory. The definition of this abstract class is as follows:

namespace System.Web.Mvc{    public abstract class ValueProviderFactory    {        public abstract IValueProvider GetValueProvider(ControllerContext controllerContext);    }}

Define a custom value provider Factory:

    public class CurrentTimeValueProviderFactory:ValueProviderFactory    {        public override IValueProvider GetValueProvider(ControllerContext controllerContext)        {            return new CurrentTimeValueProvider();        }    }

3. In the last step, we register the factory class in the application.

 public class MvcApplication : System.Web.HttpApplication    {        protected void Application_Start()        {            AreaRegistration.RegisterAllAreas();                        ValueProviderFactories.Factories.Insert(0, new CurrentTimeValueProviderFactory());            RouteConfig.RegisterRoutes(RouteTable.Routes);        }    }

2. Create a model Binder for dependency awareness.

The defaultmodelbidner class is derived and Its createmodel method is rewritten to create a di-aware binder.

1. Create a custom di-aware model binder. This class uses the dependency parser within the application scope to create model objects, and roll back to the implementation of the base class when necessary.

Public class dimodelbinder: defaultmodelbinder {protected override object createmodel (controllercontext, modelbindingcontext bindingcontext, type modeltype) {// Add di smart sensing return dependencyresolver. Current. getservice (modeltype )?? Base. createmodel (controllercontext, bindingcontext, modeltype );}}

2. We must register the di-aware binder we have defined as the default model Binder for the application. You can register it in the application_start method of Global. asax.

 

Public class mvcapplication: system. web. httpapplication {protected void application_start () {arearegistration. registerallareas (); // valueproviderfactories. factories. insert (0, new currenttimevalueproviderfactory (); valueproviderfactories. factories. add (New currenttimevalueproviderfactory (); // convert our custom model configurator to the model configurator modelbinders recognized by the application. binders. defaultbinder = new dimodelbinder (); routeconfig. registerroutes (routetable. routes );}}

3. Create a custom model Binder

Provides the imodelbinder interface to create a custom model binder.

namespace System.Web.Mvc{    public interface IModelBinder    {        object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext);    }}

Steps:

1. You can create a custom model binder by implementing the imodelbinder interface.

2. There are three methods to register the User-Defined model binder.

Method 1: register the custom model binder in the application_sart () method of the application's global. asax.

Modelbinders. binders. Add (typeof (address), new addressmodelbinder ());

Method 2: create a model binder provider. (This is a flexible method for customizing model bindings with multiple types of operations or maintaining many providers)

1) create a model binder provider by implementing the imodelbinderprovider interface. The interface is defined as follows:

namespace System.Web.Mvc{    public interface IModelBinderProvider    {        IModelBinder GetBinder(Type modelType);    }}

2) This custom model binder provider also needs to be registered in the application. Of course, it is also registered in the application_start method of Global. asax.

Suppose I have such a custom model binder provider:

  public class CustomModelBinderProvider:IModelBinderProvider    {        public IModelBinder GetBinder(Type modelType)        {            return modelType == typeof(Address) ? new AddressModerBrinder() : null;        }    }

Then I want to register the customemodelbinderprovider model binder provider, which should be like this:

  protected void Application_Start()        {            AreaRegistration.RegisterAllAreas();            ModelBinderProviders.BinderProviders.Add(new CustomModelBinderProvider());            RouteConfig.RegisterRoutes(RouteTable.Routes);        }

Method 3: Use the modelbinder annotation attribute to specify the custom model binder.

Apply the modelbinder annotation attribute to the model class and specify the model Binder for this model class.

    [ModelBinder(typeof(AddressModelBinder))]    public class Address    {        public string Line1 { get; set; }        public string Line2 { get; set; }        public string City{ get; set; }        public string PostalCode { get; set; }        public string Country { get; set; }    }

 

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.