您好,登錄后才能下訂單哦!
前面的篇幅對于IValueProvider的獲取位置和所處的生成過程做了講解,本篇將會對IValueProvider的使用做個基礎的示例講解,讀完本篇你將會對IValueProvider有個更清晰的印象。
IModelBinder、自定義Model綁定器簡單實現
Model綁定器在MVC框架中的位置
MVC中的默認Model綁定器生成過程
IModelBinderProvider的簡單應用
IValueProvider在MVC框架中生成的位置以及過程
IValueProvider的應用場景
IValueProvider的實現之NameValueCollectionValueProvider
圖1
圖1中所示的就是本篇所要演示的IValueProvider的簡單示例了。這里不對圖中的類型做講解,看下文的示例代碼自會知曉。
首先紅色方框所示的就是主要流程了,我們先來實現一下:
1. 控制器方法的定義
代碼1-1
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-2
@{ ViewBag.Title = "Index"; } <h3>Index</h3> <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
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。