前面的篇幅對於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/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面