一、创建自定义的值提供器
1.通过创建自定义的值提供器,我们可以把自己的数据源添加到模型绑定过程。而值提供器需要实现IValueProvider接口。下面是此接口的定义
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); } }
ContainsPrefix方法由模型绑定器调用,以确定这个值提供器是否可以解析给定前置的数据。
GetValue方法返回给定数据键的值,或者在值提供器无法得到合适的数据时,返回"null".
我们定义一个自定义的值提供器
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.怎么把自定义的值提供器注册给应用程序。我们需要创建一个工厂类,以创建值提供器的实例。这个类派生于抽象类ValueProviderFactory.这个抽象类的定义如下:
namespace System.Web.Mvc { public abstract class ValueProviderFactory { public abstract IValueProvider GetValueProvider(ControllerContext controllerContext); } }
定义一个自定义值提供器工厂:
public class CurrentTimeValueProviderFactory:ValueProviderFactory { public override IValueProvider GetValueProvider(ControllerContext controllerContext) { return new CurrentTimeValueProvider(); } }
3.最后一步,我们在应用程序中注册这个工厂类。
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); ValueProviderFactories.Factories.Insert(0, new CurrentTimeValueProviderFactory()); RouteConfig.RegisterRoutes(RouteTable.Routes); } }
二、创建依赖性感知的模型绑定器。
通过对DefaultModelBidner类进行派生,并重写其CreateModel方法,以创建一个DI感知的绑定器。
1、创建一个自定义的DI感知模型绑定器,这个类使用应用程序范围的依赖性解析器来创建模型对象,并在必要的时候回退到基类的实现中。
public class DIModelBinder : DefaultModelBinder { protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { //添加DI智能感知 return DependencyResolver.Current.GetService(modelType) ?? base.CreateModel(controllerContext, bindingContext, modelType); } }
2、我们必须把我定义的DI感知绑定器注册为应用程序的默认模型绑定器,可以再Global.asax的Application_Start方法中注册。
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); //ValueProviderFactories.Factories.Insert(0, new CurrentTimeValueProviderFactory()); ValueProviderFactories.Factories.Add( new CurrentTimeValueProviderFactory()); //把我們自定義的模型綁定器註冊為應用程序默認的模型綁定器 ModelBinders.Binders.DefaultBinder = new DIModelBinder(); RouteConfig.RegisterRoutes(RouteTable.Routes); } }
三、创建自定义的模型绑定器
提供IModelBinder接口,可以创建自定义的模型绑定器。
namespace System.Web.Mvc { public interface IModelBinder { object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext); } }
步骤:
1、通过实现IModelBinder接口,可以创建自定义模型绑定器。
2.注册自定义模型绑定器有三种方法。
方法一:在应用程序的Global.asax的Application_Sart()方法注册自定义的模型绑定器。
ModelBinders.Binders.Add(typeof(Address), new AddressModelBinder());
方法二:创建模型绑定器提供器。(这个对有多个类型进行操作的的自定义模型绑定器或有许多提供器要维护,这个是个灵活的方式)
1)通过实现IModelBinderProvider接口来创建一个模型绑定器提供器。这个接口的定义如下:
namespace System.Web.Mvc { public interface IModelBinderProvider { IModelBinder GetBinder(Type modelType); } }
2)这个自定义的模型绑定器提供器也需要到应用程序中注册。当然也是在Global.asax的Application_Start方法中注册。
假如我有这么个自定义模型绑定器提供器:
public class CustomModelBinderProvider:IModelBinderProvider { public IModelBinder GetBinder(Type modelType) { return modelType == typeof(Address) ? new AddressModerBrinder() : null; } }
那么我要注册CustomeModelBinderProvider 模型绑定器提供器,就应该这样:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); ModelBinderProviders.BinderProviders.Add(new CustomModelBinderProvider()); RouteConfig.RegisterRoutes(RouteTable.Routes); }
方法三:使用ModelBinder注解属性指定自定义模型绑定器。
把ModelBinder注解属性应用到模型类上,指定此模型类的模型绑定器。
[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; } }
自定义模型绑定系统