溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

ASP.NET MVC Model綁定(三)

發(fā)布時(shí)間:2020-06-19 17:10:17 來(lái)源:網(wǎng)絡(luò) 閱讀:1017 作者:jinyuan0829 欄目:編程語(yǔ)言

ASP.NET MVC Model綁定(三)

前言

看過(guò)前兩篇的朋友想必對(duì)Model綁定有個(gè)大概的了解,然而MVC框架給我們提供了更高的可擴(kuò)展性的提供程序編程模式,也就是本篇的主題了,會(huì)講解一下Model綁定器提供程序的實(shí)現(xiàn)以及解決一下上篇遺留的問(wèn)題。

第一個(gè)問(wèn)題是ModelBinderProviderCollection類(lèi)型的執(zhí)行過(guò)程?

還有個(gè)本篇的問(wèn)題就是同樣的向系統(tǒng)上下文中注冊(cè)Model綁定器和Model綁定器提供程序,哪一個(gè)優(yōu)先級(jí)更高?

 

Model綁定

  • IModelBinder、自定義Model綁定器簡(jiǎn)單實(shí)現(xiàn)

  • Model綁定器在MVC框架中的位置

  • MVC中的默認(rèn)Model綁定器生成過(guò)程

  • IModelBinderProvider的簡(jiǎn)單應(yīng)用

  • IValueProvider在MVC框架中生成的位置以及過(guò)程

  • IValueProvider的應(yīng)用場(chǎng)景

  • IValueProvider的實(shí)現(xiàn)之NameValueCollectionValueProvider

 

IModelBinderProvider的簡(jiǎn)單應(yīng)用

首先我們先看一下IModelBinderProvider類(lèi)型的定義,代碼1-1:。

代碼1-1

    public interface IModelBinderProvider
    {
        // 摘要:
        //     返回指定類(lèi)型的模型聯(lián)編程序。
        //
        // 參數(shù):
        //   modelType:
        //     模型的類(lèi)型。
        //
        // 返回結(jié)果:
        //     指定類(lèi)型的模型聯(lián)編程序。
        IModelBinder GetBinder(Type modelType);
    }

在代碼1-1中我們看出,其中的GetBinder()方法是根據(jù)ViewModel的類(lèi)型來(lái)做一些操作,最后返回Model綁定器?,F(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類(lèi)型的Model綁定器
            }
            return null;
        }
    }
}

在代碼1-2中我們根據(jù)modelType判斷是否是Customer類(lèi)型,然后返回對(duì)應(yīng)Customer類(lèi)型的Model綁定器。為什么這里的實(shí)現(xiàn)是空的,因?yàn)槲蚁氚盐覀兦懊嬷v解過(guò)的IoC框架用起來(lái),讓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)上下文了,只不過(guò)這個(gè)是給自己用的,上下文對(duì)象中想必是不會(huì)把所用到的所有數(shù)據(jù)或者是功能都添加在里面的,只是添加個(gè)引用而已,如代碼1-3中的NinjectController屬性,NinjectController屬性對(duì)應(yīng)的類(lèi)型就是NinjectController類(lèi)型,NinjectController類(lèi)型的作用就是提供IoC框架的功能,我們看一下代碼1-4中對(duì)于NinjectController類(lèi)型的定義。

代碼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ì)問(wèn)為什么不公開(kāi)個(gè)一個(gè)屬性,何必這樣多此一舉,因?yàn)槲覍?duì)Ninject的使用也不是很熟練,對(duì)于這部分的封裝我只是讓其簡(jiǎn)單的公開(kāi)了兩個(gè)功能,一個(gè)是綁定一個(gè)是獲取值,這樣讓這部分內(nèi)容還在我的可控范圍內(nèi),如果是公開(kāi)屬性的話(huà),其他人的胡亂使用導(dǎo)致錯(cuò)誤的話(huà)是不可控的。

切回主題,這樣基礎(chǔ)定義好了過(guò)后,我們?cè)傩薷?-2中的代碼,把具體實(shí)現(xiàn)給加上,示例代碼1-5所示。

代碼1-5

if (modelType == typeof(Customer))
{
    //返回對(duì)應(yīng)Customer類(lèi)型的Model綁定器
    return MVCSystemContext.Context.NinjectController.GetValueType<IModelBinder>(typeof(IModelBinder));
}

可以看到代碼1-5中,根據(jù)我們自定義上下文中的提供的IoC功能獲取到綁定在IoC框架中的值,那么綁定又是在哪里呢?跟ASP.NET MVC Model綁定(一)所演示的那樣,還是在項(xiàng)目的Global.asax文件中的MvcApplication類(lèi)型的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類(lèi)型的Model綁定器注冊(cè)到了我們自定義上下文的IoC中,然后再把針對(duì)處理Customer類(lèi)型的Model綁定器提供程序注冊(cè)到系統(tǒng)中。運(yùn)行結(jié)果如圖1.

圖1

ASP.NET MVC Model綁定(三)

其中涉及到所有部分的代碼和ASP.NET MVC Model綁定(一)篇幅中的一樣,所以這里就沒(méi)有列舉了。

在此我們根據(jù)上篇中最后圖2所示的那樣,可以判斷出ModelBinderProviderCollection類(lèi)型的執(zhí)行過(guò)程是根據(jù)當(dāng)前ParameterDescriptor類(lèi)型所提供的Model類(lèi)型對(duì)比我們注冊(cè)到或者是系統(tǒng)默認(rèn)提供的Model綁定器提供程序集合,如果有是針對(duì)ParameterDescriptor類(lèi)型所提供的Model類(lèi)型(上述示例中是Customer類(lèi)型)則會(huì)有Model綁定器的返回,然后再根據(jù)Model綁定器進(jìn)行Model綁定。

 

好了現(xiàn)在第一個(gè)問(wèn)題解決了,來(lái)解決第二個(gè)問(wèn)題。來(lái)看代碼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 類(lèi)型內(nèi)部Customer類(lèi)型實(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 類(lèi)型注冊(cè)到了系統(tǒng)的Model綁定器集合中,看一下究竟是哪一個(gè)級(jí)別更高一點(diǎn)。

來(lái)看運(yùn)行結(jié)果圖2

圖2

ASP.NET MVC Model綁定(三)

看到圖2這個(gè)結(jié)果,想必已經(jīng)知道了是哪個(gè)級(jí)別更高一點(diǎn)了。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI