前面的篇幅对于IValueProvider的获取位置和所处的生成过程作了讲解,本篇将会对IValueProvider的使用作个基础的示例讲解,读完本篇你将会对IValueProvider有个更清晰的印象。框架
图1ide
图1中所示的就是本篇所要演示的IValueProvider的简单示例了。这里不对图中的类型作讲解,看下文的示例代码自会知晓。函数
首先红色方框所示的就是主要流程了,咱们先来实现一下:spa
1. 控制器方法的定义code
代码1-1blog
namespace MvcApplication.Controllers { public class ValueProviderCaseController : Controller { public ActionResult Index(string ValueProviderCase) { ViewBag.value = ValueProviderCase; return View(); } } }
代码1-1中很简单的定义了一个Index()方法,而且参数类型(Model类型)为string类型,参数名称(Model名称)为ValueProviderCase,请你们记住这个参数名称后面会用到的。接口
2.视图呈现端代码开发
代码1-2get
@{ ViewBag.Title = "Index"; } <h2>Index</h2> <p>@ViewBag.value</p>
代码1-2为视图呈现端代码,这里用了ViewBag动态类型来传值。博客
从图1中能够看到,在执行控制器方法以前,首先要获取Model绑定器,而后是执行Model绑定器,咱们先把获取Model绑定器的部分流程放一放,先来看一下执行Model绑定器的流程。
3.自定义值提供程序的定义
从图1中看到,在执行Model绑定器的流程中,最后是执行的自定义值提供程序MyCustomValueProvider,这里咱们先无论其余的,看一下这个类型的定义:
代码1-3
using System.Web.Mvc; namespace MvcApplication.ValueProvider { public class MyCustomValueProvider:IValueProvider { public bool ContainsPrefix(string prefix) { if (prefix == "ValueProviderCase") { return true; } return false; } public ValueProviderResult GetValue(string key) { return ContainsPrefix(key) ?new ValueProviderResult( "这是一个值提供程序示例",null,System.Globalization.CultureInfo.InstalledUICulture) :null; } } }
看到代码1-3中MyCustomValueProvider的定义,小伙伴们莫慌待我慢慢解释,首先MyCustomValueProvider类型实现了IValueProvider接口类型,这个是必须的。对于IValueProvider接口类型的定义我就不放代码了,也就是MyCustomValueProvider类型的的两个方法了。
ContainsPrefix()方法的意思是值提供程序内部判断是否含有指定的前缀,把值提供程序想象成一个数据源,这个数据源中包含了键和值,这个ContainsPrefix()方法就是用来判断指定的键是否存在,若是存在的话GetValue()方法则会返回对应的值(在咱们的示例中这里的ContainsPrefix()只是做了一逻辑判断,判断当前控制器方法的参数名称【Model名称】是否为ValueProviderCase)。
而GetValue()方法的意思上面也说到了,就是用来返回指定前缀的值(指定键的值),在咱们的示例中只是返回了"这是一个值提供程序示例"。有的朋友可能发现了GetValue()方法的返回类型并非String类型,而是ValueProviderResult类型,这是MVC框架干的好事,也就是它要咱们强制的封装咱们的返回值,没办法受制于人封装就封装吧,小伙伴们看一下ValueProviderResult类型的定义:
代码1-4
public class ValueProviderResult { protected ValueProviderResult(); public ValueProviderResult(object rawValue, string attemptedValue, CultureInfo culture); public string AttemptedValue { get; protected set; } public CultureInfo Culture { get; protected set; } // // 摘要: // 获取或设置值提供程序所提供的原始值。 // // 返回结果: // 原始值。 public object RawValue { get; protected set; } public object ConvertTo(Type type); public virtual object ConvertTo(Type type, CultureInfo culture); }
看到代码1-4中的ValueProviderResult类型的构造函数定义和RawValue属性的注释了吧,而后再看一下代码1-3中GetValue()方法的代码定义,一目了然吧。
4.自定义值提供程序工厂定义
切回主要流程,咱们在使用Model绑定器中的自定义值提供程序的同时,咱们也要回想一下上一个篇幅中所讲的就是自定义值提供程序的由来,自定义值提供程序是由咱们自定义值提供程序工厂生成的,而后把这个工厂注册到系统的ValueProviderFactories. Factories中,而后会在Model绑定器执行以前生成ModelBindingContext类型实例的时候从ValueProviderFactories. Factories中获取到自定义值提供程序(MyCustomValueProvider类型)赋值到ModelBindingContext类型实例的属性ValueProvider上(对于这里的过程能够观看上一篇)。
如今咱们看一下自定义值提供程序工厂定义,代码1-5.
代码1-5
using System.Web.Mvc; namespace MvcApplication.ValueProvider { public class MyCustomValueProviderFactory:ValueProviderFactory { public override IValueProvider GetValueProvider(ControllerContext controllerContext) { if (controllerContext.Controller.GetType().Name == "ValueProviderCaseController") { return new MyCustomValueProvider(); } return null; } } }
代码1-5中GetValueProvider()方法被我添加了个逻辑判断,想指示这个工厂只为ValueProviderCaseController控制器服务,这里你们都好理解的就很少说了。
5.自定义Model绑定器
再次回到主要流程,上面说过先看Model绑定器执行部分的,如今来看Model绑定器获取部分流程。很少说直接来看自定义Model绑定器的定义,代码1-6.
代码1-6
namespace MvcApplication.Binders { public class ValueProviderModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { return bindingContext.ValueProvider.GetValue(bindingContext.ModelName).RawValue; } } }
代码1-6中经过bindingContext中的ValueProvider属性有着对值提供程序的引用,调用了代码1-3中的GetValue()方法,而且把参数名称传递过去进行逻辑判断。最后经过返回值ValueProviderResult类型的RawValue直接返回咱们定义的值。
6.将咱们自定义的"乱七八糟"类型注册到MVC框架中
经过上面那些类型的定义仍是不够的,咱们还须要将他们注册到系统中,惯例咱们在Global.asax文件中添加,固然也能够在控制器激活的过程当中进行注册,针对特定的控制器定制特定的Model绑定器,固然了在实际的项目开发实用不实用不清楚,只是这样感受Global.asax文件中会“干净”一点。不瞎扯了,来看注册的代码定义1-7.
代码1-7
ModelBinders.Binders.Add(typeof(string), new Binders.ValueProviderModelBinder()); ValueProviderFactories.Factories.Insert(0, new ValueProvider.MyCustomValueProviderFactory());
将代码1-7添加到Application_Start()方法中,首先是向系统注册了咱们自定义的Model绑定器,而后将自定义的值提供程序工厂添加到系统,这里用了Insert()方法来添加,目的是想让个人这个工厂处在默认的以前在第一个的位置,省的再一个个的去判断浪费时间。也能够用Add()方法,只不过是添加到了尾处。
最后咱们看一下结果图:
图2
做者:金源
出处:http://www.cnblogs.com/jin-yuan/
本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面