中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

ASP.NETWebAPIModel-ParameterBinding

ASP.NET Web API Model-ParameterBinding

前言

通過上個篇幅的學(xué)習(xí)了解Model綁定的基礎(chǔ)知識,然而在ASP.NET Web API中Model綁定功能模塊并不是被直接調(diào)用的,而是要通過本篇要介紹的內(nèi)容ParameterBinding的一系列對象對其進(jìn)行封裝調(diào)用,通過本篇的學(xué)習(xí)之后也會大概的清楚在Web API中綁定會有哪幾種方式。

創(chuàng)新互聯(lián)公司服務(wù)項目包括金川網(wǎng)站建設(shè)、金川網(wǎng)站制作、金川網(wǎng)頁制作以及金川網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,金川網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到金川省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

 

Model-ParameterBinding(對象篇)

在ASP.NET Web API中ParameterBinding代表著參數(shù)綁定并且在這其中涉及了幾種綁定的方式,然而ParaMeterBinding并不是單獨(dú)執(zhí)行的,就好比一個控制器方法中有可能會有多個參數(shù)一樣,所以我們就先來看一下ActionBinding的相關(guān)對象,對于這些對象的生成的環(huán)境以及過程我們在后面的篇幅中會有講解。

 

HttpActionBinding

代碼1-1

namespace System.Web.Http.Controllers
{
    public class HttpActionBinding
    {
        public HttpActionBinding();
        public HttpActionBinding(HttpActionDescriptor actionDescriptor, HttpParameterBinding[] bindings);
        public HttpActionDescriptor ActionDescriptor { get; set; }
        public HttpParameterBinding[] ParameterBindings { get; set; }

        public virtual Task ExecuteBindingAsync(HttpActionContext actionContext, CancellationToken cancellationToken);
    }
}

代碼1-1中對于HttpActionBinding類型的定義一目了然,看HttpActionBinding類型的重載構(gòu)造函數(shù)中有HttpActionDescriptor類型、HttpParameterBinding類型的數(shù)組類型作為參數(shù),HttpActionDescriptor類型作為控制器方法描述類型大家已經(jīng)很熟悉了吧,這個類型中包含著控制器方法的元數(shù)據(jù)信息,而后者HttpParameterBinding類型則是表示著參數(shù)綁定對象,其實在Model綁定中每個參數(shù)的綁定都是通過ParameterBinding來綁定的,所以這里的執(zhí)行過程我們暫時不去深入了解,就是單純的了解一下相關(guān)的對象模型。

 

HttpParameterBinding

代碼1-2

namespace System.Web.Http.Controllers
{
    public abstract class HttpParameterBinding
    {
        protected HttpParameterBinding(HttpParameterDescriptor descriptor);

        public HttpParameterDescriptor Descriptor { get; }
        public virtual string ErrorMessage { get; }
        public bool IsValid { get; }
        public virtual bool WillReadBody { get; }

        public abstract Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken);
        protected object GetValue(HttpActionContext actionContext);
        protected void SetValue(HttpActionContext actionContext, object value);
    }
}

在代碼1-2中我們看到HttpParameterBinding類型的定義,可以看到HttpParameterBinding是抽象類型,并且實現(xiàn)綁定的方法ExecuteBindingAsync()也是抽象的,這也是為了在不同的環(huán)境和情況相愛采取不同的綁定機(jī)制做好鋪墊就是多態(tài)啦,這個我們后面會說,我們還是先看下HttpParameterBinding類型的內(nèi)部定義,首先我們看到的是構(gòu)造函數(shù)中的參數(shù)類型,HttpParameterDescriptor類型,又是一個對象描述類型,這次的描述對象則是控制其方法中的某個參數(shù),而HttpParameterBinding對象實例的生成則是根據(jù)HttpParameterDescriptor對象實例而來,這個后續(xù)的篇幅中會有講解。ErrorMessage屬性表示在ParameterBinding綁定的過程中出現(xiàn)的錯誤信息,而IsValid屬性表示綁定是否可以完成的依據(jù)就是判斷ErrorMessage屬性是否為Null,WillReadBody屬性表示ParameterBinding對象是否讀取Http消息正文內(nèi)容作為參數(shù)綁定的數(shù)據(jù)源,這個稍后給大家看的示例中就有,一看便知。GetValue()和SetValue()方法就是向當(dāng)前HttpActionContext中獲取對應(yīng)的參數(shù)值和設(shè)置參數(shù)對應(yīng)值。

 

 

ModelBinderParameterBinding

代碼1-3

namespace System.Web.Http.ModelBinding
{
    public class ModelBinderParameterBinding : HttpParameterBinding, IValueProviderParameterBinding
    {
        public ModelBinderParameterBinding(HttpParameterDescriptor descriptor, IModelBinder modelBinder, IEnumerable<System.Web.Http.ValueProviders.ValueProviderFactory> valueProviderFactories);

        public IModelBinder Binder { get; }
        public IEnumerable<System.Web.Http.ValueProviders.ValueProviderFactory> ValueProviderFactories { get; }

        public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken);
    }
}

代碼1-3表示的是ModelBinderParameterBinding類型,這個類型代表的綁定方式(綁定的數(shù)據(jù)來源)是通過IModelBinder來獲取的,也就正如代碼1-3中我們看到的構(gòu)造函數(shù)一樣,其中有IModelBinder和ValueProviderFactory類型的集合,這些就是數(shù)據(jù)綁定的數(shù)據(jù)源。Binder屬性和ValueProviderFactories屬性也就是構(gòu)造函數(shù)傳入的兩個類型值。對于綁定的細(xì)節(jié)這里就不說多了。

 

FormatterParameterBinding

代碼1-4

namespace System.Web.Http.ModelBinding
{
    public class FormatterParameterBinding : HttpParameterBinding
    {
        public FormatterParameterBinding(HttpParameterDescriptor descriptor, IEnumerable<MediaTypeFormatter> formatters, IBodyModelValidator bodyModelValidator);

        public IBodyModelValidator BodyModelValidator { get; set; }
        public override string ErrorMessage { get; }
        public IEnumerable<MediaTypeFormatter> Formatters { get; set; }
        public override bool WillReadBody { get; }

        public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken);
        public virtual Task<object> ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable<MediaTypeFormatter> formatters, IFormatterLogger formatterLogger);
    }
}

代碼1-4中所示的FormatterParameterBinding類型是通過哪種方式來獲取綁定數(shù)據(jù)源的呢?大家可以看到WillReadBody屬性在這個類型中被重寫了,原來在HttpParameterBinding類型中默認(rèn)為false的是不會對Http請求的正文內(nèi)容進(jìn)行讀寫的,而這里在FormatterParameterBinding類型中,已然的重寫了,說明在這個類型中我們所能用到的綁定數(shù)據(jù)源就是從Http請求的正文內(nèi)容來讀取了,然而Http請求的正文內(nèi)容并不是直接放在那里供我們讀取的,而是在客戶端發(fā)送前就已經(jīng)被指定的序列化器序列化了。

那么我們在服務(wù)器端就要反序列化才能獲取到值,這里在代碼1-4中我們看到構(gòu)造函數(shù)中可以看到和代碼1-3一樣都是具有一個HttpParameterDescriptor類型的參數(shù)對象,而后則是一個MediaTypeFormatter類型的集合對象,最后是進(jìn)行Model驗證的對象,這個后續(xù)再說。

現(xiàn)在我們就來看看第二個參數(shù)類型中的MediaTypeFormatter類型。

 

MediaTypeFormatter

代碼1-5

namespace System.Net.Http.Formatting
{
    public abstract class MediaTypeFormatter
    {
        protected MediaTypeFormatter();
        public abstract bool CanReadType(Type type);
        public abstract bool CanWriteType(Type type);
        public virtual Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger);
        public virtual Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext);
    }
}

在代碼1-5中所示的MediaTypeFormatter類型是被刪減過的一部分,所剩4個方法中兩個是抽象方法兩個是虛方法,先看兩個抽象方法的定義,CanReadType()方法表示的是根據(jù)指定的參數(shù)類型從當(dāng)前的Http請求正文中能否讀取到改類型的值,簡單來說就是能否把正文內(nèi)容反序列化為指定的參數(shù)類型,同理CanWriterType()是對響應(yīng)正文進(jìn)行操作判斷。而ReadFromStreamAsync()方法和WriteToStreamAsync()方法則是對Http請求正文內(nèi)容和Http響應(yīng)正文內(nèi)容進(jìn)行實際操作的兩個方法。

 

對于MediaTypeFormatter類型的實現(xiàn)類型比如說針對Json格式的JsonMediaTypeFormatter和針對Xml格式的XmlMediaTypeFormatter.

 

我們看一下JsonMediaTypeFormatter類型的簡單示例,大家就會知道是怎么回事了。

首先我們在服務(wù)器端的控制器中定義一個接收Post請求的方法,

代碼1-6

        [CustomControllerActionAuthorizationFilter]
        public void Post(Product product)
        {
            products.Add(product);
        }

為了方便演示在其控制其方法上加了個授權(quán)過濾器,然后我們對Post請求的處理使用JsonMediaTypeFormatter類型進(jìn)行反序列化的操作將在CustomControllerActionAuthorizationFilter過濾器類型中進(jìn)行。

代碼1-7

public Task<System.Net.Http.HttpResponseMessage> ExecuteAuthorizationFilterAsync(System.Web.Http.Controllers.HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<System.Net.Http.HttpResponseMessage>> continuation)
        {
            Console.WriteLine(actionContext.Request.Content.Headers.ContentType.MediaType);

            IEnumerable<MediaTypeFormatter> formatters = new MediaTypeFormatter[] 
            {
                new JsonMediaTypeFormatter()
            };
            Product product = actionContext.Request.Content.ReadAsAsync<Common.Product>(formatters).Result;
            Console.WriteLine(product.ProductID);
            Console.WriteLine(product.ProductName);
            Console.WriteLine(product.ProductCategory);
            return continuation();
        }

在代碼1-7中,在請求到達(dá)控制器方法之前會先經(jīng)過授權(quán)過濾器,在這其中首先我們是先向服務(wù)器端的控制器輸出了當(dāng)前請求的格式類型,然后就對當(dāng)前請求的正文內(nèi)容使用JsonMediaTypeFormatter類型進(jìn)行反序列化操作。

我們再看下客戶端使用HttpClient類型進(jìn)行模擬Post請求,

代碼1-8

            HttpClient httpClient = new HttpClient();
            Product product = new Product()
            {
                ProductID = "003",
                ProductName = "旺仔牛奶",
                ProductCategory = "食品類"
            };
            await httpClient.PostAsJsonAsync<Product>("http://localhost/selfhost/api/product", product);

最后結(jié)果如圖1.

圖1

ASP.NET Web API Model-ParameterBinding

看到這里想必大家也知道對于XmlMediaTypeFormatter的使用方式是怎樣的了。

還有一種MediaTypeFormatter類型FormUrlEncodedMediaTypeFormatter類型,F(xiàn)ormUrlEncodedMediaTypeFormatter類型表示的是在Http Post請求中表單提交的數(shù)據(jù)所用格式器,我們看一下FormUrlEncodedMediaTypeFormatter類型中CanReadType()方法的實現(xiàn)。

代碼1-9

    public override bool CanReadType(Type type)
    {
        if (type == null)
        {
            throw Error.ArgumentNull("type");
        }
        if (!(type == typeof(FormDataCollection)))
        {
            return FormattingUtilities.IsJTokenType(type);
        }
        return true;
    }

在代碼1-9我們可以看到FormDataCollection類型實際就是IEnumerable<KeyValuePair<string,string>>類型的對象,在表單提交后的請求Url中大家也都可以看到是是key=value的形式,所以這里就是這種格式的。對于這個格式器的示例會在后面的篇幅給大家做演示講解。

 

HttpRequestParameterBinding

最后我們再看一個RequestParameterBinding對象。

代碼1-10

    public class HttpRequestParameterBinding : HttpParameterBinding
    {
        // Methods
        public HttpRequestParameterBinding(HttpParameterDescriptor descriptor)
            : base(descriptor)
        {
        }

        public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
        {
            string parameterName = base.Descriptor.ParameterName;
            HttpRequestMessage request = actionContext.ControllerContext.Request;
            actionContext.ActionArguments.Add(parameterName, request);
            return TaskHelpers.Completed();
        }
    }

在代碼1-10中我們看到再ExecuteBindingAsync()方法的實現(xiàn)中,是直接獲取到參數(shù)名稱和當(dāng)前的請求對象,然后添加到控制其方法執(zhí)行上下文的ActionArguments屬性中,在之前的篇幅中也說過這個屬性用來存放方法對應(yīng)參數(shù)值(Model綁定后的值)。

本篇關(guān)于ParameterBinding的對象介紹就到這里,都是零零散散的不過在后面的篇幅中都會有示例介紹說明的。

網(wǎng)站名稱:ASP.NETWebAPIModel-ParameterBinding
地址分享:http://www.rwnh.cn/article32/gpoipc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、App開發(fā)、虛擬主機(jī)、服務(wù)器托管網(wǎng)站收錄、域名注冊

廣告

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

商城網(wǎng)站建設(shè)
萝北县| 麟游县| 大化| 清远市| 陇南市| 余庆县| 阳山县| 驻马店市| 时尚| 东乡族自治县| 宜城市| 壶关县| 中超| 闻喜县| 克山县| 新巴尔虎左旗| 都匀市| 双桥区| 太保市| 宽甸| 乌兰察布市| 东海县| 翁牛特旗| 于都县| 武冈市| 巢湖市| 鹿邑县| 新余市| 丰镇市| 许昌县| 沭阳县| 奉新县| 高州市| 临江市| 内乡县| 上林县| 高邮市| 资源县| 和顺县| 博兴县| 永善县|