看過前兩篇的朋友想必對(duì)Model綁定有個(gè)大概的了解,然而MVC框架給我們提供了更高的可擴(kuò)展性的提供程序編程模式,也就是本篇的主題了,會(huì)講解一下Model綁定器提供程序的實(shí)現(xiàn)以及解決一下上篇遺留的問題。
網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了花垣免費(fèi)建站歡迎大家使用!
第一個(gè)問題是ModelBinderProviderCollection類型的執(zhí)行過程?
還有個(gè)本篇的問題就是同樣的向系統(tǒng)上下文中注冊(cè)Model綁定器和Model綁定器提供程序,哪一個(gè)優(yōu)先級(jí)更高?
IModelBinder、自定義Model綁定器簡(jiǎn)單實(shí)現(xiàn)
Model綁定器在MVC框架中的位置
MVC中的默認(rèn)Model綁定器生成過程
IModelBinderProvider的簡(jiǎn)單應(yīng)用
IValueProvider在MVC框架中生成的位置以及過程
IValueProvider的應(yīng)用場(chǎng)景
IValueProvider的實(shí)現(xiàn)之NameValueCollectionValueProvider
首先我們先看一下IModelBinderProvider類型的定義,代碼1-1:。
代碼1-1
public interface IModelBinderProvider
{
// 摘要:
// 返回指定類型的模型聯(lián)編程序。
//
// 參數(shù):
// modelType:
// 模型的類型。
//
// 返回結(jié)果:
// 指定類型的模型聯(lián)編程序。
IModelBinder GetBinder(Type modelType);
}在代碼1-1中我們看出,其中的GetBinder()方法是根據(jù)ViewModel的類型來做一些操作,最后返回Model綁定器。現(xiàn)在我們自定義實(shí)現(xiàn)一個(gè)Model綁定器提供程序代碼1-2。
代碼1-2
using System.Web.Mvc;
using ConsoleApplication2;
namespace MvcApplication.Infrastructure
{
public class MyCustomModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(Type modelType)
{
if (modelType == null)
{
throw new ArgumentNullException("modelType");
}
if (modelType == typeof(Customer))
{
//返回對(duì)應(yīng)Customer類型的Model綁定器
}
return null;
}
}
}在代碼1-2中我們根據(jù)modelType判斷是否是Customer類型,然后返回對(duì)應(yīng)Customer類型的Model綁定器。為什么這里的實(shí)現(xiàn)是空的,因?yàn)槲蚁氚盐覀兦懊嬷v解過的IoC框架用起來,讓Model綁定器提供程序跟Model綁定器解除耦合,想把IoC框架的應(yīng)用定義在當(dāng)前系統(tǒng)的上下文中,我們看一下代碼實(shí)現(xiàn),代碼1-3。
代碼1-3
namespace MvcApplication
{
public class MVCSystemContext
{
private static MVCSystemContext _MVCSystemContext;
public static MVCSystemContext Context
{
get
{
if (_MVCSystemContext == null)
{
_MVCSystemContext = new MVCSystemContext();
}
return _MVCSystemContext;
}
}
private ServiceContainer _serviceContainer;
private MVCSystemContext()
{
_serviceContainer = new ServiceContainer();
_serviceContainer.AddService(typeof(NinjectController),NinjectController.Instance);
}
public NinjectController NinjectController
{
get
{
return (NinjectController)_serviceContainer.GetService(typeof(NinjectController));
}
}
}
}代碼1-3當(dāng)中就是我定義的當(dāng)前系統(tǒng)上下文了,只不過這個(gè)是給自己用的,上下文對(duì)象中想必是不會(huì)把所用到的所有數(shù)據(jù)或者是功能都添加在里面的,只是添加個(gè)引用而已,如代碼1-3中的NinjectController屬性,NinjectController屬性對(duì)應(yīng)的類型就是NinjectController類型,NinjectController類型的作用就是提供IoC框架的功能,我們看一下代碼1-4中對(duì)于NinjectController類型的定義。
代碼1-4
using Ninject;
namespace MvcApplication.Infrastructure.NinjectControllerPart
{
public class NinjectController
{
private static NinjectController _Instance;
public static NinjectController Instance
{
get
{
return _Instance = new NinjectController();
}
}
private IKernel _ninjectKernel;
private NinjectController()
{
_ninjectKernel = new StandardKernel();
}
public void AddKernelBind<T, U>()where U:T
{
_ninjectKernel.Bind<T>().To<U>();
}
public T GetValueType<T>(Type keyType)
{
var valueType = _ninjectKernel.Get(keyType);
return (T)valueType;
}
}
}其中對(duì)于Ninject這個(gè)IoC框架進(jìn)行了一個(gè)最基礎(chǔ)的功能封裝,有的朋友可能會(huì)問為什么不公開個(gè)一個(gè)屬性,何必這樣多此一舉,因?yàn)槲覍?duì)Ninject的使用也不是很熟練,對(duì)于這部分的封裝我只是讓其簡(jiǎn)單的公開了兩個(gè)功能,一個(gè)是綁定一個(gè)是獲取值,這樣讓這部分內(nèi)容還在我的可控范圍內(nèi),如果是公開屬性的話,其他人的胡亂使用導(dǎo)致錯(cuò)誤的話是不可控的。
切回主題,這樣基礎(chǔ)定義好了過后,我們?cè)傩薷?-2中的代碼,把具體實(shí)現(xiàn)給加上,示例代碼1-5所示。
代碼1-5
if (modelType == typeof(Customer))
{
//返回對(duì)應(yīng)Customer類型的Model綁定器
return MVCSystemContext.Context.NinjectController.GetValueType<IModelBinder>(typeof(IModelBinder));
}可以看到代碼1-5中,根據(jù)我們自定義上下文中的提供的IoC功能獲取到綁定在IoC框架中的值,那么綁定又是在哪里呢?跟ASP.NET MVC Model綁定(一)所演示的那樣,還是在項(xiàng)目的Global.asax文件中的MvcApplication類型的Application_Start()方法中添加如代碼1-6。
代碼1-6
MVCSystemContext.Context.NinjectController.AddKernelBind<IModelBinder, Binders.MyCustomModelBinder>(); ModelBinderProviders.BinderProviders.Add(new MyCustomModelBinderProvider());
代碼1-6分別做了兩個(gè)操作,先是把對(duì)應(yīng)Customer類型的Model綁定器注冊(cè)到了我們自定義上下文的IoC中,然后再把針對(duì)處理Customer類型的Model綁定器提供程序注冊(cè)到系統(tǒng)中。運(yùn)行結(jié)果如圖1.
圖1

其中涉及到所有部分的代碼和ASP.NET MVC Model綁定(一)篇幅中的一樣,所以這里就沒有列舉了。
在此我們根據(jù)上篇中最后圖2所示的那樣,可以判斷出ModelBinderProviderCollection類型的執(zhí)行過程是根據(jù)當(dāng)前ParameterDescriptor類型所提供的Model類型對(duì)比我們注冊(cè)到或者是系統(tǒng)默認(rèn)提供的Model綁定器提供程序集合,如果有是針對(duì)ParameterDescriptor類型所提供的Model類型(上述示例中是Customer類型)則會(huì)有Model綁定器的返回,然后再根據(jù)Model綁定器進(jìn)行Model綁定。
好了現(xiàn)在第一個(gè)問題解決了,來解決第二個(gè)問題。來看代碼1-7所示。
代碼1-7
public class MyCustomModelBinder:IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return new Customer()
{
CustomerID = "010",
Name = "測(cè)試人員",
RegistrationDate = DateTime.Now,
Address = new Address()
{
AddressName = "天空之城"
}
};
}
}
public class MyCustomModelBinder_Test : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return new Customer()
{
CustomerID = "010",
Name = "測(cè)試人員",
RegistrationDate = DateTime.Now,
Address = new Address()
{
AddressName = "這里是根據(jù)Model綁定器綁定執(zhí)行的Model"
}
};
}
}看到代碼1-7中的MyCustomModelBinder_Test 類型內(nèi)部Customer類型實(shí)例內(nèi)部的AddressName值已經(jīng)更改的和之前的不一樣了。再看一***冊(cè)端的修改,示例代碼1-8。
代碼1-8
ModelBinders.Binders.Add(typeof(Customer), new Binders.MyCustomModelBinder_Test()); MVCSystemContext.Context.NinjectController.AddKernelBind<IModelBinder, Binders.MyCustomModelBinder>(); ModelBinderProviders.BinderProviders.Add(new MyCustomModelBinderProvider());
代碼1-8中,我們把新定義的MyCustomModelBinder_Test 類型注冊(cè)到了系統(tǒng)的Model綁定器集合中,看一下究竟是哪一個(gè)級(jí)別更高一點(diǎn)。
來看運(yùn)行結(jié)果圖2
圖2

看到圖2這個(gè)結(jié)果,想必已經(jīng)知道了是哪個(gè)級(jí)別更高一點(diǎn)了。
網(wǎng)頁(yè)名稱:ASP.NETMVCModel綁定(三)
URL標(biāo)題:http://chinadenli.net/article12/ppdpdc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、關(guān)鍵詞優(yōu)化、Google、網(wǎng)站收錄、網(wǎng)站策劃、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)