ASP.NETMVCModel綁定(四)-創(chuàng)新互聯(lián)

ASP.NET MVC Model綁定(四)

前言

前面的篇幅對于Model綁定器IModelBinder以及實(shí)現(xiàn)類型、Model綁定器提供程序都作了粗略的講解,可以把Model綁定器想象成一個(gè)大的容器,為什么這么說呢?留個(gè)疑問在這里。

創(chuàng)新互聯(lián)建站專業(yè)IDC數(shù)據(jù)服務(wù)器托管提供商,專業(yè)提供成都服務(wù)器托管,服務(wù)器租用,服務(wù)器托管服務(wù)器托管,成都多線服務(wù)器托管等服務(wù)器托管服務(wù)。

首先控制器的方法參數(shù)可能是很多種類型的、可能是多個(gè)同一種類型的,應(yīng)對這種情況MVC框架使用的綁定實(shí)現(xiàn)都是IValueProvider來做的,而針對參數(shù)類型的不同等等一些情況,IValueProvider的實(shí)現(xiàn)類型也是有很大的差異的,這些具體實(shí)現(xiàn)的講解會(huì)在后續(xù)的篇幅中講解。

都說旁觀者清,我們不要走進(jìn)MVC框架,站在外面看。本篇會(huì)已站在外面的角度去對IValueProvider做個(gè)描述。

Model綁定

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

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

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

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

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

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

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

IValueProvider在MVC框架中生成的位置以及過程

生成的位置

大家可否記得在ASP.NET MVC Model綁定(二)中對于Model綁定器生成位置的描述,這里借用一下那副描述生成位置的示意圖,

圖1

ASP.NET MVC Model綁定(四)

圖1中所示,藍(lán)色線條執(zhí)行流程中,在Model綁定器生成后,即會(huì)生成IValueProvider類型,說是生成有點(diǎn)不妥,改成獲取吧。為什么這樣說在下面的生成部分會(huì)講到

生成的過程

我們先看一下圖1中藍(lán)色線條流程的實(shí)現(xiàn)代碼。

代碼1-1

protected virtual object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
        {
            Type parameterType = parameterDescriptor.ParameterType;
            IModelBinder modelBinder = this.GetModelBinder(parameterDescriptor);
            IValueProvider valueProvider = controllerContext.Controller.ValueProvider;
            string str = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName;
            Predicate<string> propertyFilter = GetPropertyFilter(parameterDescriptor);
            ModelBindingContext context2 = new ModelBindingContext
            {
                FallbackToEmptyPrefix = parameterDescriptor.BindingInfo.Prefix == null,
                ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, parameterType),
                ModelName = str,
                ModelState = controllerContext.Controller.ViewData.ModelState,
                PropertyFilter = propertyFilter,
                ValueProvider = valueProvider
            };
            ModelBindingContext bindingContext = context2;
            return (modelBinder.BindModel(controllerContext, bindingContext) ?? parameterDescriptor.DefaultValue);
        }

對于代碼1-1中所示的方法,不用去管的它的返回類型以及這個(gè)方法的作用,我們現(xiàn)在想知道的就是IValueProvider是怎么來的?。?!

從代碼1-1中,我們可以明確的看到在生成Model綁定器過后,MVC框架從ControllerContext控制器上下文參數(shù)對象中獲得了當(dāng)前請求所請求的控制器的引用,然后根據(jù)當(dāng)前的控制器對象引用獲取到IValueProvider類型。

然后MVC框架會(huì)實(shí)例化ModelBindingContext類型,并且把剛剛獲取的IValueProvider類型賦值到其中的ValueProvider屬性上。

對于ModelBindingContext類型,Model綁定上下文對象,看下它的定義代碼1-2。

代碼1-2

public class ModelBindingContext
    {
        public ModelBindingContext();
        public ModelBindingContext(ModelBindingContext bindingContext);
        public bool FallbackToEmptyPrefix { get; set; }
        public object Model { get; set; }
        public ModelMetadata ModelMetadata { get; set; }
        public string ModelName { get; set; }
        public ModelStateDictionary ModelState { get; set; }
        public Type ModelType { get; set; }
        public Predicate<string> PropertyFilter { get; set; }
        public IDictionary<string, ModelMetadata> PropertyMetadata { get; }
        //
        // 摘要:
        //     獲取或設(shè)置值提供程序。
        //
        // 返回結(jié)果:
        //     值提供程序。
        public IValueProvider ValueProvider { get; set; }
    }

這里我們只需初步的了解ModelBindingContext類型就行了,回到主題中,上面說到從當(dāng)前控制器對象的引用中直接獲取的,那我們就去看一下控制器中的ValueProvider屬性。我們就來看一下Controller類型,代碼1-3.

代碼1-3

public abstract class Controller : ControllerBase, IActionFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter
{
   ……
}

跟大家開了個(gè)玩笑,緩解下氣氛。Controller類型中并沒有我們所要找的屬性,有的朋友想到了,對的是在基類類型中的,確實(shí)是在ControllerBase類型中的(代碼1-4)。

代碼1-4

public abstract class ControllerBase : IController
{
   ……
   public IValueProvider ValueProvider { get; set; }
}

難道我們在使用IValueProvider的時(shí)候是要賦值到控制器對象上的嗎?

當(dāng)然不是了,我們看一下代碼1-4中ValueProvider屬性的實(shí)現(xiàn),示例代碼1-5.

代碼1-5

public IValueProvider ValueProvider
        {
            get
            {
                if (this._valueProvider == null)
                {
                    this._valueProvider = ValueProviderFactories.Factories.GetValueProvider(this.ControllerContext);
                }
                return this._valueProvider;
            }
            set
            {
                this._valueProvider = value;
            }
        }

看到這里想必大家就應(yīng)該已經(jīng)了解了IValueProvider類型的由來了,是從系統(tǒng)的ValueProviderFactories類型的Factories屬性中來根據(jù)當(dāng)前控制器上下文獲取到的。

這里我們看一下生成IValueProvider類型的幾個(gè)相關(guān)類型的定義,示例代碼1-6。

代碼1-6

    public static class ValueProviderFactories
    {
        // 摘要:
        //     獲取應(yīng)用程序的值提供程序工廠的集合。
        //
        // 返回結(jié)果:
        //     值提供程序工廠對象的集合。
        public static ValueProviderFactoryCollection Factories { get; }
    }

    public class ValueProviderFactoryCollection : Collection<ValueProviderFactory>
    {
        public ValueProviderFactoryCollection();
        public ValueProviderFactoryCollection(IList<ValueProviderFactory> list);

        // 摘要:
        //     為指定控制器上下文返回值提供程序工廠。
        //
        // 參數(shù):
        //   controllerContext:
        //     一個(gè)對象,該對象封裝有關(guān)當(dāng)前 HTTP 請求的信息。
        //
        // 返回結(jié)果:
        //     用于指定控制器上下文的值提供程序工廠對象。
        public IValueProvider GetValueProvider(ControllerContext controllerContext);
        protected override void InsertItem(int index, ValueProviderFactory item);
        protected override void SetItem(int index, ValueProviderFactory item);
    }

    public abstract class ValueProviderFactory
    {
       
        protected ValueProviderFactory();

        // 摘要:
        //     為指定控制器上下文返回值提供程序?qū)ο蟆?        //
        // 參數(shù):
        //   controllerContext:
        //     一個(gè)對象,該對象封裝有關(guān)當(dāng)前 HTTP 請求的信息。
        //
        // 返回結(jié)果:
        //     值提供程序?qū)ο蟆?        public abstract IValueProvider GetValueProvider(ControllerContext controllerContext);
    }

ValueProviderFactories類型的這種模式前面見過太多了,就不說了,它里面包含著ValueProviderFactoryCollection類型的靜態(tài)屬性,而ValueProviderFactoryCollection類型又是ValueProviderFactory類型的集合類型,所以在最終生成IValueProvider類型的時(shí)候也是先遍歷ValueProviderFactoryCollection類型,獲取每個(gè)ValueProviderFactory類型的實(shí)例并且來生成IValueProvider類型,這里也是最先匹配而不是最優(yōu)匹配。

這里捎帶一句,可以用控制器上下文對象來對ValueProviderFactory類型中的生成邏輯進(jìn)行分類,針對不同的控制器生成不同的IValueProvider類型。對于IValueProvider類型的使用后面篇幅會(huì)有說明。

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開啟,新人活動(dòng)云服務(wù)器買多久送多久。

當(dāng)前標(biāo)題:ASP.NETMVCModel綁定(四)-創(chuàng)新互聯(lián)
文章位置:http://muchs.cn/article6/dpegig.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊云服務(wù)器、網(wǎng)站策劃、網(wǎng)站制作網(wǎng)站設(shè)計(jì)公司、App設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計(jì)公司