完成OSS.Http底層HttpClient重構(gòu)封裝 支持標(biāo)準(zhǔn)庫(kù)
OSS.Http項(xiàng)目對(duì)于.Net Standard標(biāo)準(zhǔn)庫(kù)的支持已經(jīng)遷移完畢,OSS開(kāi)源系列兩個(gè)最底層的類庫(kù)已經(jīng)具備跨運(yùn)行時(shí)支持的能力。由于OSS.Http類庫(kù)是幾年前我參照RestSharp的思路,完成的一個(gè)輕量型Http請(qǐng)求框架。因?yàn)闀r(shí)間較久底層使用的還是HttpWebRequest,這次基本上是完全重構(gòu),這篇文章主要包含 1. HttpClient的介紹,2. 重構(gòu)的思路, 3. 容易遇到的問(wèn)題。
一. httpclient的基本介紹
HttpClient應(yīng)該是在.net framework4.5版本左右引用的新功能,在此之前常用的是HttpWebRequest,相比較而言,前者更加的簡(jiǎn)單清晰,最重要的是完全支持.net standard API,這也是我選擇它的重要原因。
HttpClient在結(jié)構(gòu)上做了很大的調(diào)整,并且是完全異步的實(shí)現(xiàn),可以說(shuō)從底層上完成了異步的支持,這里先介紹對(duì)應(yīng)的幾個(gè)主要類:
1. HtttpRequestMessage
請(qǐng)求的基本信息,請(qǐng)求地址,請(qǐng)求動(dòng)作等,此值是在HttpClient發(fā)起請(qǐng)求的方法中當(dāng)參數(shù)傳入,與他對(duì)應(yīng)的是響應(yīng) HttpResponseMessage
2. HttpContent
請(qǐng)求的內(nèi)容體,主要包含請(qǐng)求的具體內(nèi)容,contenttype,contentlenght等,是HtttpRequestMessage的一個(gè)屬性,這兩個(gè)都包含Headers屬性,但是范圍分別不一樣,這個(gè)是很容易混淆出錯(cuò)的地方,我給做了簡(jiǎn)單分類:
HttpRequestMessage的頭部(HttpRequestHeaders )主要是請(qǐng)求的屬性,如Accept,UserAgent,AcceptEncoding等http鏈接的基本屬性。
HttpContent的頭部(HttpContentHeaders)主要是當(dāng)前請(qǐng)求內(nèi)容的屬性,主要有:Allow,Content-Encoding,Content-Length,Content-Type ,Expires ,Last-Modified 等,詳見(jiàn)官方類庫(kù)。
HttpContent 系統(tǒng)提供了幾個(gè)默認(rèn)實(shí)現(xiàn),主要如下幾個(gè):
3. HttpMessageHandler
此類主要作用是請(qǐng)求內(nèi)容處理動(dòng)作等的定義,如是否支持重定向,是否可以使用cookie,代理Proxy等,偏向于系統(tǒng)的設(shè)置,可以此值通過(guò)HttpClient構(gòu)造函數(shù)傳入其中,系統(tǒng)默認(rèn)的提供的子類為HttpClientHandler。
4. HttpClient
具體的請(qǐng)求實(shí)現(xiàn)調(diào)用實(shí)現(xiàn),完整實(shí)現(xiàn)了POST,GET,Delete等Http請(qǐng)求方法,所有的方法最終調(diào)用的是SendAsync方法。
上邊的四個(gè)主要類,構(gòu)成了HttpClient請(qǐng)求的主要實(shí)現(xiàn),如果你只是簡(jiǎn)單的使用,那么只需要關(guān)心HttpClient即可,如下:
其實(shí)在它內(nèi)部已經(jīng)默認(rèn)實(shí)現(xiàn)了HttpRequestMessage和HttpClientHandler的賦值。
雖然簡(jiǎn)單介紹,但是基本上可以看出,HttpClient的實(shí)現(xiàn)做了非常明確的分工,不是再像以前所有的設(shè)置都集中在webrequest中。分工的明確最直接的優(yōu)勢(shì)是HttpClient實(shí)現(xiàn)了多請(qǐng)求共用,參見(jiàn)博文:
The default HttpClient is the simplest way in which you can start sending requests. A single HttpClient can be used to send as many HTTP requests as you want concurrently so in many scenarios you can just create one HttpClient and then use that for all your requests.
也就是當(dāng)你系統(tǒng)中要發(fā)起不同的請(qǐng)求時(shí),可以共用一個(gè)HttpClient,而不用像HttpWebReqest基本每次請(qǐng)求都需要重新定義一個(gè)對(duì)象,以減少資源的消耗。
二. 重構(gòu)OSS.Http
回到正題,重構(gòu)我們的當(dāng)前代碼模塊,如我所說(shuō),由于.Net Standard下完全不提供httpWebRequest的支持,直接導(dǎo)致了我做出重新實(shí)現(xiàn)的決定,因?yàn)橐郧癶ttpWebRequest的簡(jiǎn)陋,所以我基本上做了很大的封裝框架,上層完全不需要接觸具體的底層實(shí)現(xiàn),基本上實(shí)現(xiàn)了RestSharp的核心,有興趣的同學(xué)可以參考代碼 OSS.Http 下Old分支。
重構(gòu)之前由于對(duì)HttpClient不是十分了解,本想延續(xù)已有框架流程,轉(zhuǎn)換實(shí)現(xiàn)。不過(guò)隨著對(duì)Client文檔的查看研究,發(fā)現(xiàn)很多封裝已經(jīng)完全不需要,流程也發(fā)生了變化,所以刪除很多原來(lái)框架下的東西,重新整理出最終的實(shí)現(xiàn)。
當(dāng)然現(xiàn)在的HttpClient本身實(shí)現(xiàn)已經(jīng)足夠簡(jiǎn)單清晰,不過(guò)在很多情況下直接調(diào)用POST,GET等方法,會(huì)減少部分代碼的重用,像在OSS.Social項(xiàng)目中,底層我只需要實(shí)現(xiàn)一個(gè)RestCommon方法,即可達(dá)到全局請(qǐng)求控制,調(diào)用方只需要提供Url,HttpMothed,Parameter即可。
這里我畫(huà)了一個(gè)簡(jiǎn)單的流程圖作為呈現(xiàn):
流程基本沒(méi)有太大的出入,代碼在Github,文件的結(jié)構(gòu)如下:
Mos文件下: Enum.cs 枚舉類,F(xiàn)ileParameter.cs 文件參數(shù)類,F(xiàn)ormParameter Form表單參數(shù)類 ,OsHttpRequest 請(qǐng)求參數(shù)類,
OsRest.cs 是當(dāng)前封裝類的主要實(shí)現(xiàn),同時(shí)為了保證HttpClient本身功能通用,OsRest繼承自HttpClient,同時(shí)提供了RestSend方法,在這個(gè)方法中完成流程的實(shí)現(xiàn)并最終調(diào)用SendAsync方法執(zhí)行請(qǐng)求。
RestUtil.cs 輔助類,完成了全局OsRest(HttpClient)的共用,并定義了一個(gè)默認(rèn)HttpClientHandler實(shí)現(xiàn),正常直接調(diào)用這個(gè)類就可以了。
流程中的執(zhí)行用戶自定義設(shè)置,可以在OSHttpRequest中的RequestSet委托屬性中設(shè)置,例如可以設(shè)置訪問(wèn)類型是json:
三. 容易遇到的問(wèn)題
雖然整個(gè)重構(gòu)后的代碼已經(jīng)不多了,但是應(yīng)該還是有些問(wèn)題可以給大家分享下
1. Header賦值問(wèn)題,請(qǐng)參見(jiàn)我第一部分,一定要分清不同Headers,否則就可能給你報(bào)不正確的值錯(cuò)誤
2. 可以發(fā)現(xiàn)上邊的流程圖中有個(gè)“是否是Get”的判斷,因?yàn)槿绻荊et請(qǐng)求,Content是不能賦值的,就像在HttpWebReqest中,如果get請(qǐng)求調(diào)用了GetRequestStream方法,會(huì)有“無(wú)法發(fā)送具有此謂詞類型的內(nèi)容正文”的異常錯(cuò)誤。當(dāng)然如果你使用的是OSS.Http作為請(qǐng)求,那么就沒(méi)有這個(gè)問(wèn)題了。
3. 和上傳文件同時(shí)上傳的表單參數(shù),與單獨(dú)的表單參數(shù)提交,是不一樣的,請(qǐng)注意處理,不懂得參見(jiàn)OsRest類即可,已經(jīng)做了處理。
如果你還有其他問(wèn)題,或者對(duì)后續(xù)的更新感興趣,請(qǐng)關(guān)注公眾號(hào)(OSSCoder):
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持我們!
上一篇:C# 泛型的約束
欄 目:C#教程
本文標(biāo)題:完成OSS.Http底層HttpClient重構(gòu)封裝 支持標(biāo)準(zhǔn)庫(kù)
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/5916.html
您可能感興趣的文章


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開(kāi)的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻 器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過(guò)重寫(xiě)Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 04-02jquery與jsp,用jquery
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10delphi制作wav文件的方法
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改