日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

.net的retrofit--WebApiClient底层篇

發布時間:2023/12/4 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .net的retrofit--WebApiClient底层篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

本篇文章的內容是WebApiClient底層說明,也是WebApiClient系列接近尾聲的一篇文章,如果你沒有閱讀過之前的的相關文章,可能會覺得本文章的內容斷層

庫簡介

WebApiClient是開源在github上的一個httpClient客戶端庫,內部基于HttpClient開發,是一個只需要定義c#接口(interface),并打上相關特性,即可異步調用http-api的框架 ,支持.net framework4.5+、netcoreapp2.0和netstandard2.0。
WebApiClient是我2017年看到java的retrofit庫之后,決心給.net打造的一款面向切面的httpclient客戶端庫,在開發過程中陸續發現.net下也有一些HttpClient包裝庫,WebApiClient庫雖然是后起,卻有其它庫所沒有很多優秀特征:

  • 原生的支持面向切面編程;

  • 內置豐富的特性,支持自定義特性;

  • 靈活和Filter、GlobalFilter和IParameterable;

  • 功能強大的序列化工具;

  • 與外部HttpClientHandler無縫銜接;

  • 獨一無二的請求異常條件重試功能和異常處理鏈式語法功能

1. HttpRequestMessage簡說

System.Net.Http.HttpRequestMessage表示一個請求消息,一般而言它包含一個完整的請求數據,主要由請求頭和請求體組成,對于Post、Delete、Put等請求,其Content屬性包含提交的數據體內容。

WebApiClient的ApiActionContex對象有個RequestMessage對象,是派生于HttpRequestMessage,同時實現了多個Addxxx方法用于給其屬性Content對象添加數據內容。

2. HttpClientHandler簡說

System.Net.Http.HttpClientHandler是一個與tcp層相關的對象,負責與遠程服務器進行tcp連接,將HttpRequestMessage轉換為http請求包發送給服務端,并等待服務端的響應。(以上這段話是我瞎說,僅供討論)一般的網絡相關配置的證書、代理和認證等在都在這里可以配置。

3. HttpClient簡說

System.Net.Http.HttpClient必須與HttpClientHandler關聯才能使用,一個HttpRequestMessage經過HttpClient之后,HttpClient的一些默認配置會影響到它,比如默認請求頭等。HttpClient是使用關聯的HttpClientHandler將HttpRequestMessage發送出去,也就是說,完全可以跳過HttpClient而使用HttpClientHandler來發送請求,方法是寫一個類,繼承于HttpClientHandler并公開一個方法,調用基類的SendAsync方法就可以發送請求。

4. WebApiClient庫的HttpClient配置

WebApiClient庫是對HttpClient的封裝,所有的配置項在HttpApiConfig對象, 實例化HttpApiConfig對象時有個構造器可以傳入IHttpClient的實例,而IHttpClient是對System.Net.Http.HttpClient的一個包裝接口定義,WebApiClient.Defaults.HttpClient是對IHttpClient接口的一個實現,才下代碼是WebApiCient與System.Net.Http.HttpClient的一個銜接:

IHttpClient client = new WebApiClient.Defaults.HttpClient();var config = new WebApiClient.HttpApiConfig(client);

5. IHttpClient接口

5.1 IHttpClient的接口定義

/// <summary> 定義HttpClient的接口

/// </summary>
public interface IHttpClient : IDisposable{ ? ?
? ? /// <summary>/// 獲取關聯的Http處理對象/// </summary>HttpClientHandler Handler { get; } ? ?
? ?/// <summary>/// 獲取默認的請求頭管理對象/// </summary>HttpRequestHeaders DefaultRequestHeaders { get; } ? ?
? ?/// <summary>/// 異步發送請求/// </summary>/// <param name="request">請求消息</param>/// <returns></returns>Task<HttpResponseMessage> SendAsync(HttpApiRequestMessage request);... }

5.2 IHttpClient的接口意圖

IHttpClient接口意圖將System.Net.Http.HttpClient實例和System.Net.Http.HttpClientHandler實例進行組合封裝,隱藏底層的一些細節,同時描述了HttpClient和HttpClientHandler不可分割的關系,其默認實現對象WebApiClient.Defaults.HttpClient將System.Net.Http.HttpClient難用的幾個功能也封裝了一次:比如設置Cookie和設置代理等。

5.3 更換WebApiClient.Defaults.HttpClient關聯的HttpClientHandler

一般而言,HttpClient沒有多少擴展的價值,但HttpClientHandler就有很多擴展空間,其中System.Net.Http.WebRequestHandler也派生于HttpClientHandler,多了很一些配置的屬性,很多時候,需要替換WebApiClient.Defaults.HttpClient的HttpClientHandler就可以,而不用從頭實現IHttpClient接口,以下方式可以替換HttpClientHandler:

class MyHttpClient : WebApiClient.Defaults.HttpClient{ ?

?protected override HttpClientHandler CreateHttpClientHandler(){ ? ? ? ?// or return your handlerreturn new WebRequestHandler();} } var config = new HttpApiConfig(new MyHttpClient());var myWebApi = HttpApiClient.Create(config);

如果是外部的HttpClientHandler實例,可以使用如下方式關聯:

var client = new WebApiClient.Defaults.HttpClient(handler);
var config = new HttpApiConfig(client);
var myWebApi = HttpApiClient.Create(config);

6. 擴展JsonFormatter

WebApiClient.Defaults.JsonFormatter使用了json.net,每次序列化或反序列化時都會創建JsonSerializerSettings,可以派生WebApiClient.Defaults.JsonFormatter返回自定義的JsonSerializerSettings:

class MyJsonFormatter : WebApiClient.Defaults.JsonFormatter{ ?
?protected override JsonSerializerSettings CreateSerializerSettings(){ ? ? ?
??return new JsonSerializerSettings{ ? ? ? ? ? ?// your setting};} }
??var config = new HttpApiConfig{ ?
???JsonFormatter = new MyJsonFormatter() };
???var myWebApi = HttpApiClient.Create(config);

7. 擴展WebApiClient.Defaults.KeyValueFormatter

KeyValueFormatter基于Middleware思想,內部由多個轉換器相連組成,隨著轉換器的增加,支持的類型也更多,KeyValueFormatter默認支持序列化以下類型:

  • 1、常用簡單類型及其空類型(byte、int、short、long、doublue、flout、string、decimal、DateTime、Guid、enum、Version和Uri)

  • 2、支持IEnumerable遞歸拆解,默認最多16層

  • 3、KeyValuePair<,>的任意泛型

  • 4、多屬性模型的第一層屬性拆解

如果你需要支持更多的類型,需要派生KeyValueFormatter增加功能:

class MyKeValueFormatter : WebApiClient.Defaults.KeyValueFormatter

{

? ? protected override IEnumerable<ConverterBase> GetConverters()

? ? {

? ? ? ? // 在原有轉換器之前插入DynamicObjectConverter

? ? ? ? var addin = new[] { new DynamicObjectConverter() };

? ? ? ? return addin.Concat(base.GetConverters());

? ? }

}


/// <summary>

/// 表示動態類型轉換器

/// </summary>

class DynamicObjectConverter : ConverterBase

{

? ? /// <summary>

? ? /// 執行轉換

? ? /// </summary>

? ? /// <param name="context">轉換上下文</param>

? ? /// <returns></returns>

? ? public override IEnumerable<KeyValuePair<string, string>> Invoke(ConvertContext context)

? ? {

? ? ? ? var dynamicObject = context.Data as DynamicObject;

? ? ? ? if (dynamicObject != null)

? ? ? ? {

? ? ? ? ? ? return from name in dynamicObject.GetDynamicMemberNames()

? ? ? ? ? ? ? ? ? ?let value = this.GetValue(dynamicObject, name)

? ? ? ? ? ? ? ? ? ?let ctx = new ConvertContext(name, value, context.Depths, context.Options)

? ? ? ? ? ? ? ? ? ?select ctx.ToKeyValuePair();

? ? ? ? }


? ? ? ? return this.Next.Invoke(context);

? ? }


? ? /// <summary>

? ? /// 獲取動態類型的值

? ? /// </summary>

? ? /// <param name="dynamicObject">實例</param>

? ? /// <param name="name">名稱</param>

? ? /// <returns></returns>

? ? private object GetValue(DynamicObject dynamicObject, string name)

? ? {

? ? ? ? object value;

? ? ? ? var binder = new MemberBinder(name);

? ? ? ? dynamicObject.TryGetMember(binder, out value);

? ? ? ? return value;

? ? }


? ? /// <summary>

? ? /// 表示成員值的獲取綁定

? ? /// </summary>

? ? private class MemberBinder : GetMemberBinder

? ? {

? ? ? ? /// <summary>

? ? ? ? /// 鍵的信息獲取綁定

? ? ? ? /// </summary>

? ? ? ? /// <param name="key">鍵名</param>

? ? ? ? public MemberBinder(string key)

? ? ? ? ? ? : base(key, false)

? ? ? ? {

? ? ? ? }


? ? ? ? /// <summary>

? ? ? ? /// 在派生類中重寫時,如果無法綁定目標動態對象,則執行動態獲取成員操作的綁定

? ? ? ? /// </summary>

? ? ? ? /// <param name="target"></param>

? ? ? ? /// <param name="errorSuggestion"></param>

? ? ? ? /// <returns></returns>

? ? ? ? public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)

? ? ? ? {

? ? ? ? ? ? throw new NotImplementedException();

? ? ? ? }

? ? }

}

相關內容:?

  • 自動類型安全的REST .NET標準庫refit

  • WebApi client 的面向切面編程

  • net的retrofit--WebApiClient庫

  • .net的retrofit--WebApiClient庫深入篇

原文地址:https://www.cnblogs.com/kewei/p/8302382.html


.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com

總結

以上是生活随笔為你收集整理的.net的retrofit--WebApiClient底层篇的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。