亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

ASP.NET Web API Model-ModelBinder

2019-11-17 01:46:08
字體:
來源:轉載
供稿:網友

asp.net Web API Model-ModelBinder

ASP.NET Web API Model-ModelBinder

前言

本篇中會為大家介紹在ASP.NET Web API中ModelBinder的綁定原理以及涉及到的一些對象模型,還有簡單的Model綁定示例,在前面的篇幅中講解了Model元數據、ValuePRovider的模塊,然后還有本篇的Model綁定的模塊這些會結合到后面篇幅中的ParameterBinder模塊中來使用,也就是說在ASP.NET Web API框架中綁定的方式有兩種實現,都是通過ParameterBinder來對參數進行綁定,而在ParameterBinder中的實現則會有兩種方式,今天就給大家單獨的說明一下Model綁定,把它看成一個單獨的功能模塊就行了。

Model-ModelBinder

不瞎扯了,直接進入主題,首先我們來看IModelBinder接口類型的定義,所有的ModelBinder功能模塊都實現了IModelBinder接口,如示例代碼1-1

示例代碼1-1

IModelBinder

namespace System.Web.Http.ModelBinding{    public interface IModelBinder    {        bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext);    }}

在代碼1-1中我們可以看到BindModel()方法中定義了兩個參數而且都是上下文類型的參數,第一個上下文參數表示操作上下文,它是在控制器方法被執行之前就被創建并且其中封裝了一些后續操作必要的信息以及存儲請求、響應和參數綁定的結果值,這個稍后會跟大家講解,它起到一個很重要的作用。

第二個上下文參數是綁定上下文參數,這個容易理解,意思就是對象里封裝著本次要綁定對象的信息也就是Model元數據、ValueProvider之類的信息,現在不理解也沒關系慢慢往后看看完就會明白的。

HttpActionContext

代碼1-2

namespace System.Web.Http.Controllers{    public class HttpActionContext    {        public HttpActionContext();        public HttpActionContext(HttpControllerContext controllerContext, HttpActionDescriptor actionDescriptor);        public Dictionary<string, object> ActionArguments { get; }        public HttpActionDescriptor ActionDescriptor { get; set; }        public HttpControllerContext ControllerContext { get; set; }        public ModelStateDictionary ModelState { get; }        public HttpRequestMessage Request { get; }        public HttpResponseMessage Response { get; set; }    }}

代碼1-2就是HttpActionContext類型的定義了,下面簡單的描述一下幾個屬性所表示的含義,ActionArguments屬性中的值是對應著控制器方法的參數列表,其中Key值就是參數名稱,Value值就是參數的實際數據值了,因為Model綁定是一個遞歸的過程在復雜類型的子項綁定完畢后并不會對這個屬性進行賦值,而是等這一個參數項全部綁定完成了才會進行賦值。

HttpActionDescriptor類型的ActionDescriptor屬性,這個是HttpControllerDescriptor類型之后所見的第二個這種描述類型,后面還會有HttpParameterDescriptor類型,在這里ActionDescriptor屬性中就是封裝著當前所要請求的控制器方法信息,類似封裝著方法的元數據信息。

ControllerContext屬性就不用多說了想必大家也都知道它的作用,ModelStateDictionary類型的ModelState屬性則是在Model綁定之后才會對其操作,是把參數綁定驗證后的值存在這個屬性當中。

HttpActionContextExtensions

代碼1-3

namespace System.Web.Http.Controllers{    // 摘要:    //     包含 System.Web.Http.Controllers.HttpActionContext 的擴展方法。    [EditorBrowsable(EditorBrowsableState.Never)]    public static class HttpActionContextExtensions    {        public static bool Bind(this HttpActionContext actionContext, ModelBindingContext bindingContext);        public static bool Bind(this HttpActionContext actionContext, ModelBindingContext bindingContext, IEnumerable<IModelBinder> binders);        //……    }}

代碼1-3的所示的是包含HttpActionContext類型的擴展方法類型HttpActionContextExtensions,我們在這之中可以看到兩個Bind()方法,這兩個Bind()也是Model綁定至關重要的地方,因為Model綁定的遞歸就是在這里實現的,至于怎么實現的稍后會說。

這里的第一個Bind()方法其實就是調用第二個Bind()方法來執行的。而第二Bind()方法中IEnumerable<IModelBinder>參數則是從HttpActionContext類型中獲取到當前的HttpControllerContext并且再從其中獲取到當前請求的配置對象HttpConfiguration對象,最后從配置對象中的容器屬性中獲取ModelBinder的提供程序集合,然后根據當前ModelBindingContext中的ModelType類型使用提供程序集合來判斷后獲取適合類型的IModelBinder集合,從而調用第二個Bind()方法。

這樣看可能還是不太理解遞歸的情況,大家稍安勿躁,后面慢慢講解。

ModelBindingContext

代碼1-4

namespace System.Web.Http.ModelBinding{    // 摘要:    //     提供運行模型聯編程序的上下文。    public class ModelBindingContext    {        // 摘要:        //     初始化 System.Web.Http.ModelBinding.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; }        public IDictionary<string, ModelMetadata> PropertyMetadata { get; }        public ModelValidationNode ValidationNode { get; set; }        public IValueProvider ValueProvider { get; set; }    }}

代碼1-4中所示的就是綁定上下文對象,首先我們看到它的重載構造函數中有個ModelBindingContext類型的參數用以表示嵌套,內部的實現是用以傳遞ModelState屬性的狀態值和ValueProvider值提供程序,至于為什么是這種結構?這個跟綁定復雜類型的時候有關,構造就如同ModelState屬性對象的ModelStateDictionary類型一樣,這種結構稍后會講解。

當中的Model屬性表示當前ModelBindingContext中綁定過后的Model值,然后ModelMetadata、ModelName、ModelType、PropertyMetadata這些屬性都是表示當前ModelBindingContext中Model的對應值。這個”當前”可能是string類型,也可能是復雜類型。(復雜類型在綁定的時候會被ASP.NET Web API框架封裝起來有個特定的類型,這個稍后講解)

簡單類型綁定器以及綁定器提供程序

簡單類型綁定器- TypeConverterModelBinder

代碼1-5

    public sealed class TypeConverterModelBinder : IModelBinder    {        // Methods        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)        {            object obj2;            ModelBindingHelper.ValidateBindingContext(bindingContext);            ValueProviderResult result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);            if (result == null)            {                return false;            }            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, result);            try            {                obj2 = result.ConvertTo(bindingContext.ModelType);            }            catch (Exception exception)            {                if (IsFormatException(exception))                {                    string errorMessage = ModelBinderConfig.TypeConversionErrorMessageProvider(actionContext, bindingContext.ModelMetadata, result.AttemptedValue);                    if (errorMessage != null)                    {                        bindingContext.ModelState.AddModelError(bindingContext.ModelName, errorMessage);                    }                }                else                {                    bindingContext.ModelState.AddModelError(bindingContext.ModelName, exception);                }                return false;            }            ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref obj2);            bindingContext.Model = obj2;            return true;        }}

在代碼1-5中,我們看到TypeConverterModelBinder類型實現了IModelBinder接口,并且在BindModel()方法中直接就是使用綁定上下文中的ValueProvider根據綁定上下文中的ModelName屬性,ModelName就是我們前面ValueProvider篇幅中講解到的前綴值和屬性值的合并。而后會將獲取到的結果值進行類型判斷,如果不能正確的轉換成string類型則會提示各種異常,當然了這種異常不會報出來,只是添加到了當前綁定上下文的ModelState屬性中,如果可以轉換成功則會對當前綁定上下文的Model值進行賦值。

簡單類型綁定器提供程序- TypeConverterModelBinderProvider

代碼1-6

    public sealed class TypeConverterModelBinderProvider : ModelBinderProvider    {        // Methods        public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType)        {            if (modelType == null)            {                throw Error.ArgumentNull("modelType");            }            if (!TypeHelper.HasStringConverter(modelType))            {                return null;            }            return new TypeConverterModelBinder();        }    }

代碼1-6中所示TypeConverterModelBinderProvider類型則為簡單類型綁定器的提供程序,并且繼承自ModelBinderProvider類型,講到這里了我才發現我把這個類型忘記說明了,不過沒關系,大家自行看一下就好了,ModelBinderProvider就是一個抽象類,然后定義了一個抽象的行為。

在TypeConverterModelBinderProvider類型的實現中,我們可以清楚的看到如果參數modelType可以成功的轉換成string類型則會返回TypeConverterModelBinder類型的實例,不然則返回null。

復雜類型綁定器(封裝器)以及復雜類型綁定器(封裝器)提供程序

復雜類型封裝對象-ComplexModelDto

代碼1-7

namespace System.Web.Http.ModelBinding.Binders{    // 摘要:    //     表示一個復雜模型的數據傳輸對象 (DTO)。    public class ComplexModelDto    {        public ComplexModelDto(ModelMetadata modelMetadata, IEnumerable<ModelMetadata> propertyMetadata);        public ModelMetadata ModelMetadata { get; }        public Collection<ModelMetadata> PropertyMetadata { get; }        public IDictionary<ModelMetadata, ComplexModelDtoResult> Results { get; }    }}

大家也看到了代碼1-7中的注釋部分,表示一個復雜模型(Model)的數據傳輸對象,實際就是對復雜類型的重新封裝,封裝的方式大家也看到了都是以Model元數據的方式,這個類型我就不多說了。對于Model元數據不太清楚的朋友

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
4388成人网| 成人春色激情网| 亚洲丁香久久久| 亚洲色图五月天| 大伊人狠狠躁夜夜躁av一区| 98视频在线噜噜噜国产| 狠狠色狠狠色综合日日五| 成人黄色免费网站在线观看| 精品国产一区二区三区久久狼5月| 国产91九色视频| 在线精品国产欧美| 国产午夜精品理论片a级探花| 久久久999精品| 亚洲免费成人av电影| 欧美激情视频在线免费观看 欧美视频免费一| 日本精品在线视频| 91成人精品网站| 欧美日韩国产中文字幕| 亚洲日韩中文字幕在线播放| 精品欧美国产一区二区三区| 国产日本欧美在线观看| 亚洲欧美第一页| 亚洲成色777777在线观看影院| 国产精品久久久久久网站| 91视频-88av| 韩国三级电影久久久久久| 日韩成人在线视频网站| 日韩欧美中文第一页| 欧美日韩另类视频| 欧美一区二区三区图| 美女福利视频一区| 91极品女神在线| 亚洲国产天堂久久国产91| 亚洲女人天堂成人av在线| 欧美视频一二三| 成人午夜激情网| 欧美日韩在线观看视频小说| 欧美亚洲国产日本| 日韩在线观看成人| 国产精品露脸自拍| 奇米四色中文综合久久| 日韩中文字幕精品| 日韩中文字幕在线看| 成人有码在线视频| 欧美精品久久久久| 亚洲欧美国产va在线影院| 国产91热爆ts人妖在线| 国产性猛交xxxx免费看久久| 日韩久久精品电影| 性亚洲最疯狂xxxx高清| 精品中文字幕乱| 日韩在线小视频| 亚洲人高潮女人毛茸茸| 久久久久久国产| 国内精品视频一区| 在线日韩av观看| 亚洲高清一区二| 欧美性资源免费| 亚洲欧美在线磁力| 91在线观看免费网站| 777国产偷窥盗摄精品视频| 亚洲国产成人在线视频| 日韩精品免费综合视频在线播放| 粗暴蹂躏中文一区二区三区| 欧美在线视频网站| 欧美精品videossex88| 日韩中文字幕在线| 精品久久久中文| 欧美重口另类videos人妖| 亚洲欧美日韩精品久久奇米色影视| 97国产精品人人爽人人做| 日韩欧美aⅴ综合网站发布| 中文字幕日本精品| 成人午夜黄色影院| 欧美成人免费全部| 国产精品成人品| 91久久久久久久久久久久久| 岛国精品视频在线播放| 国产精品日韩一区| 亲爱的老师9免费观看全集电视剧| 亚洲视频一区二区三区| 国产精品旅馆在线| 亚洲人成人99网站| 91久久精品久久国产性色也91| 亚洲美女久久久| 中文字幕自拍vr一区二区三区| 国产精品香蕉在线观看| 欧美激情三级免费| 国内外成人免费激情在线视频网站| 不用播放器成人网| 欧洲美女免费图片一区| 欧美最近摘花xxxx摘花| 777国产偷窥盗摄精品视频| 欧美精品久久久久久久久| 精品亚洲一区二区三区在线播放| 色www亚洲国产张柏芝| 久久久国产精品视频| 日本伊人精品一区二区三区介绍| 久久天堂电影网| 日韩在线欧美在线| 亚洲一区二区三区香蕉| 92看片淫黄大片看国产片| 一本一本久久a久久精品牛牛影视| 欧美人在线观看| 伊人伊成久久人综合网小说| 国产91露脸中文字幕在线| 国产精品久久久久久av福利软件| 久久精品视频亚洲| 第一福利永久视频精品| 97精品欧美一区二区三区| 亚洲国产成人精品久久久国产成人一区| 亚洲精品午夜精品| 国产suv精品一区二区三区88区| 1769国内精品视频在线播放| 亚洲精品美女在线观看| 国产综合福利在线| 日韩中文字幕视频在线| 久久久久久高潮国产精品视| 456国产精品| 国产一区二区三区视频| 成人a免费视频| 深夜福利91大全| 国产小视频国产精品| 亚洲欧洲中文天堂| 久久精品成人欧美大片古装| 日韩在线视频导航| 欧美中文字幕在线播放| 国产精品jizz在线观看麻豆| 国产69精品久久久久9999| 疯狂蹂躏欧美一区二区精品| 性亚洲最疯狂xxxx高清| 色av吧综合网| 久久综合网hezyo| 日韩中文字幕网| 欧美激情喷水视频| 欧美大片网站在线观看| 欧美日韩精品在线播放| 中文字幕久热精品视频在线| 欧美视频二区36p| 亚洲第一免费播放区| 久久久999成人| 精品性高朝久久久久久久| 日韩精品极品在线观看播放免费视频| 亚洲视频综合网| 欧美日韩在线一区| 国产成人av网| 亚洲欧美精品一区| 欧美中文字幕视频| 久久久精品美女| 欧美性猛交xxxx黑人| 国产精品爱久久久久久久| 亚洲综合成人婷婷小说| 91在线国产电影| 日韩欧美亚洲一二三区| 精品国产视频在线| 日韩美女中文字幕| 亚洲精品少妇网址| 日韩视频免费在线| 久久精品青青大伊人av| 久久99热精品| 国产精品jvid在线观看蜜臀| 伊人久久久久久久久久久| 不卡av日日日| 亚洲人成网站999久久久综合|