OSS.Http項目對於.Net Standard標準庫的支援已經遷移完畢,OSS開源系列兩個最底層的類庫已經具備跨運行時支援的能力。本篇文章主要包含 1. HttpClient的介紹,2. 重構的思路, 3. 容易遇到的問題。具有很好的參考價值,下面跟著小編一起來看下吧
OSS.Http項目對於.Net Standard標準庫的支援已經遷移完畢,OSS開源系列兩個最底層的類庫已經具備跨運行時支援的能力。由於OSS.Http類庫是幾年前我參照RestSharp的思路,完成的一個輕量型Http請求架構。因為時間較久底層使用的還是HttpWebRequest,這次基本上是完全重構,這篇文章主要包含 1. HttpClient的介紹,2. 重構的思路, 3. 容易遇到的問題。
一. httpclient的基本介紹
HttpClient應該是在.net framework4.5版本左右引用的新功能,在此之前常用的是HttpWebRequest,相比較而言,前者更加的簡單清晰,最重要的是完全支援.net standard API,這也是我選擇它的重要原因。
HttpClient在結構上做了很大的調整,並且是完全非同步實現,可以說從底層上完成了非同步支援,這裡先介紹對應的幾個主要類:
1. HtttpRequestMessage
請求的基本資料,請求地址,請求動作等,此值是在HttpClient發起請求的方法中當參數傳入,與他對應的是響應 HttpResponseMessage
2. HttpContent
請求的內容體,主要包含請求的具體內容,contenttype,contentlenght等,是HtttpRequestMessage的一個屬性,這兩個都包含Headers屬性,但是範圍分別不一樣,這個是很容易混淆出錯的地方,我給做了簡單分類:
HttpRequestMessage的頭部(HttpRequestHeaders )主要是請求的屬性,如Accept,UserAgent,AcceptEncoding等http連結的基本屬性。
HttpContent的頭部(HttpContentHeaders)主要是當前請求內容的屬性,主要有:Allow,Content-Encoding,Content-Length,Content-Type ,Expires ,Last-Modified 等,詳見官方類庫。
HttpContent 系統提供了幾個預設實現,主要如下幾個:
3. HttpMessageHandler
此類主要作用是請求內容處理動作等的定義,如是否支援重新導向,是否可以使用cookie,代理Proxy等,偏向於系統的設定,可以此值通過HttpClient建構函式傳入其中,系統預設的提供的子類為HttpClientHandler。
4. HttpClient
具體的請求實現調用實現,完整實現了POST,GET,Delete等Http要求方法,所有的方法最終調用的是SendAsync方法。
上邊的四個主要類,構成了HttpClient請求的主要實現,如果你只是簡單的使用,那麼只需要關心HttpClient即可,如下:
其實在它內部已經預設實現了HttpRequestMessage和HttpClientHandler的賦值。
雖然簡單介紹,但是基本上可以看出,HttpClient的實現做了非常明確的分工,不是再像以前所有的設定都集中在webrequest中。分工的明確最直接的優勢是HttpClient實現了多請求共用,參見博文:
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.
也就是當你系統中要發起不同的請求時,可以共用一個HttpClient,而不用像HttpWebReqest基本每次請求都需要重新定義一個對象,以減少資源的消耗。
二. 重構OSS.Http
回到正題,重構我們的當前代碼模組,如我所說,由於.Net Standard下完全不提供httpWebRequest的支援,直接導致了我做出重新實現的決定,因為以前httpWebRequest的簡陋,所以我基本上做了很大的封裝架構,上層完全不需要接觸具體的底層實現,基本上實現了RestSharp的核心,有興趣的同學可以參考代碼 OSS.Http 下Old分支。
重構之前由於對HttpClient不是十分瞭解,本想延續已有架構流程,轉換實現。不過隨著對Client文檔的查看研究,發現很多封裝已經完全不需要,流程也發生了變化,所以刪除很多原來架構下的東西,重新整理出最終的實現。
當然現在的HttpClient本身實現已經足夠簡單清晰,不過在很多情況下直接調用POST,GET等方法,會減少部分代碼的重用,像在OSS.Social項目中,底層我只需要實現一個RestCommon方法,即可達到全域請求控制,調用方只需要提供Url,HttpMothed,Parameter即可。
這裡我畫了一個簡單的流程圖作為呈現:
流程基本沒有太大的出入,代碼在Github,檔案的結構如下:
Mos檔案下: Enum.cs 枚舉類,FileParameter.cs 檔案參數類,FormParameter Form表單參數類 ,OsHttpRequest 請求參數類,
OsRest.cs 是當前封裝類的主要實現,同時為了保證HttpClient本身功能通用,OsRest繼承自HttpClient,同時提供了RestSend方法,在這個方法中完成流程的實現並最終調用SendAsync方法執行請求。
RestUtil.cs 輔助類,完成了全域OsRest(HttpClient)的共用,並定義了一個預設HttpClientHandler實現,正常直接調用這個類就可以了。
流程中的執行使用者自訂設定,可以在OSHttpRequest中的RequestSet委託屬性中設定,例如可以設定訪問類型是json:
三. 容易遇到的問題
雖然整個重構後的代碼已經不多了,但是應該還是有些問題可以給大家分享下
1. Header賦值問題,請參見我第一部分,一定要分清不同Headers,否則就可能給你報不正確的值錯誤
2. 可以發現上邊的流程圖中有個“是否是Get”的判斷,因為如果是Get請求,Content是不能賦值的,就像在HttpWebReqest中,如果get請求調用了GetRequestStream方法,會有“無法發送具有此謂詞類型的內容本文”的異常錯誤。當然如果你使用的是OSS.Http作為請求,那麼就沒有這個問題了。
3. 和上傳檔案同時上傳的表單參數,與單獨的表單參數提交,是不一樣的,請注意處理,不懂得參見OsRest類即可,已經做了處理。
以上就是完成OSS.Http底層HttpClient重構封裝 支援標準庫的詳細介紹的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!