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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

使用自定义DelegatingHandler编写更整洁的Typed HttpClient

發(fā)布時(shí)間:2023/12/4 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用自定义DelegatingHandler编写更整洁的Typed HttpClient 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用自定義DelegatingHandler編寫更整潔的Typed HttpClient

簡(jiǎn)介

我寫了很多HttpClient[1],包括類型化的客戶端。自從我發(fā)現(xiàn)Refit[2]以來(lái),我只使用了那一個(gè),所以我只編寫了很少的代碼!但是我想到了你!你們中的某些人不一定會(huì)使用Refit,[3]因此,我將為您提供一些技巧,以使用HttpClient消息處理程序[4](尤其是DelegatingHandlers)[5]編寫具有最大可重用性的類型化HttpClient[6]

編寫類型化的HttpClient來(lái)轉(zhuǎn)發(fā)JWT并記錄錯(cuò)誤

這是要整理的HttpClient[7]

using DemoRefit.Models; using DemoRefit.Repositories; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks;namespace DemoRefit.HttpClients {public class CountryRepositoryClient : ICountryRepositoryClient{private readonly HttpClient _client;private readonly IHttpContextAccessor _httpContextAccessor;private readonly ILogger<CountryRepositoryClient> _logger;public CountryRepositoryClient(HttpClient client, ILogger<CountryRepositoryClient> logger, IHttpContextAccessor httpContextAccessor){_client = client;_logger = logger;_httpContextAccessor = httpContextAccessor;}public async Task<IEnumerable<Country>> GetAsync(){try{string accessToken = await _httpContextAccessor.HttpContext.GetTokenAsync("access_token");if (string.IsNullOrEmpty(accessToken)){throw new Exception("Access token is missing");}_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", accessToken);var headers = _httpContextAccessor.HttpContext.Request.Headers;if (headers.ContainsKey("X-Correlation-ID") && !string.IsNullOrEmpty(headers["X-Correlation-ID"])){_client.DefaultRequestHeaders.Add("X-Correlation-ID", headers["X-Correlation-ID"].ToString());}using (HttpResponseMessage response = await _client.GetAsync("/api/democrud")){response.EnsureSuccessStatusCode();return await response.Content.ReadAsAsync<IEnumerable<Country>>();}}catch (Exception e){_logger.LogError(e, "Failed to run http query");return null;}}} }

這里有許多事情需要清理,因?yàn)樗鼈冊(cè)谀鷮⒃谕粦?yīng)用程序中編寫的每個(gè)客戶端中可能都是多余的:

?從HttpContext讀取訪問令牌?令牌為空時(shí),管理訪問令牌?將訪問令牌附加到HttpClient[8]進(jìn)行委派?從HttpContext讀取CorrelationId?將CorrelationId附加到HttpClient[9]進(jìn)行委托?使用EnsureSuccessStatusCode()驗(yàn)證Http查詢是否成功

編寫自定義的DelegatingHandler來(lái)處理冗余代碼

這是DelegatingHandler[10]

using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using System; using System.Net.Http; using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks;namespace DemoRefit.Handlers {public class MyDelegatingHandler : DelegatingHandler{private readonly IHttpContextAccessor _httpContextAccessor;private readonly ILogger<MyDelegatingHandler> _logger;public MyDelegatingHandler(IHttpContextAccessor httpContextAccessor, ILogger<MyDelegatingHandler> logger){_httpContextAccessor = httpContextAccessor;_logger = logger;}protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken){HttpResponseMessage httpResponseMessage;try{string accessToken = await _httpContextAccessor.HttpContext.GetTokenAsync("access_token");if (string.IsNullOrEmpty(accessToken)){throw new Exception($"Access token is missing for the request {request.RequestUri}");}request.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);var headers = _httpContextAccessor.HttpContext.Request.Headers;if (headers.ContainsKey("X-Correlation-ID") && !string.IsNullOrEmpty(headers["X-Correlation-ID"])){request.Headers.Add("X-Correlation-ID", headers["X-Correlation-ID"].ToString());}httpResponseMessage = await base.SendAsync(request, cancellationToken);httpResponseMessage.EnsureSuccessStatusCode();}catch (Exception ex){_logger.LogError(ex, "Failed to run http query {RequestUri}", request.RequestUri);throw;}return httpResponseMessage;}} }

如您所見,現(xiàn)在它封裝了用于同一應(yīng)用程序中每個(gè)HttpClient[11]的冗余邏輯 。

現(xiàn)在,清理后的HttpClient[12]如下所示:

using DemoRefit.Models; using DemoRefit.Repositories; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks;namespace DemoRefit.HttpClients {public class CountryRepositoryClientV2 : ICountryRepositoryClient{private readonly HttpClient _client;private readonly ILogger<CountryRepositoryClient> _logger;public CountryRepositoryClientV2(HttpClient client, ILogger<CountryRepositoryClient> logger){_client = client;_logger = logger;}public async Task<IEnumerable<Country>> GetAsync(){using (HttpResponseMessage response = await _client.GetAsync("/api/democrud")){try{return await response.Content.ReadAsAsync<IEnumerable<Country>>();}catch (Exception e){_logger.LogError(e, "Failed to read content");return null;}}}} }

好多了不是嗎?????

最后,讓我們將DelegatingHandler[13]附加到Startup.cs中的HttpClient[14]

using DemoRefit.Handlers; using DemoRefit.HttpClients; using DemoRefit.Repositories; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Refit; using System;namespace DemoRefit {public class Startup{public Startup(IConfiguration configuration){Configuration = configuration;}public IConfiguration Configuration { get; }// This method gets called by the runtime. Use this method to add services to the container.public void ConfigureServices(IServiceCollection services){services.AddHttpContextAccessor();services.AddControllers();services.AddHttpClient<ICountryRepositoryClient, CountryRepositoryClientV2>().ConfigureHttpClient(c => c.BaseAddress = new Uri(Configuration.GetSection("Apis:CountryApi:Url").Value)).AddHttpMessageHandler<MyDelegatingHandler>();}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseHttpsRedirection();app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapControllers();});}} }

使用Refit

如果您正在使用Refit[15],則絕對(duì)可以重用該DelegatingHandler[16]

例:

using DemoRefit.Handlers; using DemoRefit.HttpClients; using DemoRefit.Repositories; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Refit; using System;namespace DemoRefit {public class Startup{public Startup(IConfiguration configuration){Configuration = configuration;}public IConfiguration Configuration { get; }// This method gets called by the runtime. Use this method to add services to the container.public void ConfigureServices(IServiceCollection services){services.AddHttpContextAccessor();services.AddControllers();services.AddRefitClient<ICountryRepositoryClient>().ConfigureHttpClient(c => c.BaseAddress = new Uri(Configuration.GetSection("Apis:CountryApi:Url").Value));.AddHttpMessageHandler<MyDelegatingHandler>();}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseHttpsRedirection();app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapControllers();});}} }

輪子介紹:

Refit是一個(gè)深受Square的 Retrofit 庫(kù)啟發(fā)的庫(kù),目前在github上共有star 4000枚,通過(guò)這個(gè)框架,可以把你的REST API變成了一個(gè)活的接口:

public interface IGitHubApi {[Get("/users/{user}")]Task<User> GetUser(string user); }

RestService類生成一個(gè)IGitHubApi的實(shí)現(xiàn),它使用HttpClient進(jìn)行調(diào)用:

var gitHubApi = RestService.For<IGitHubApi>("https://api.github.com");var octocat = await gitHubApi.GetUser("octocat");

查看更多:https://reactiveui.github.io/refit/

References

[1]?HttpClient:?https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netcore-3.0
[2]?Refit:?https://github.com/reactiveui/refit
[3]?Refit,:?https://github.com/reactiveui/refit
[4]?HttpClient消息處理程序:?https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/httpclient-message-handlers
[5]?DelegatingHandlers):?https://docs.microsoft.com/en-us/dotnet/api/system.net.http.delegatinghandler?view=netframework-4.8
[6]?類型化HttpClient:?https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests
[7]?鍵入的HttpClient:?https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests
[8]?HttpClient:?https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netcore-3.0
[9]?HttpClient:?https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netcore-3.0
[10]?DelegatingHandler:?https://docs.microsoft.com/en-us/dotnet/api/system.net.http.delegatinghandler?view=netframework-4.8
[11]?HttpClient:?https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netcore-3.0
[12]?HttpClient:?https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netcore-3.0
[13]?DelegatingHandler:?https://docs.microsoft.com/en-us/dotnet/api/system.net.http.delegatinghandler?view=netframework-4.8
[14]?HttpClient:?https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netcore-3.0
[15]?Refit:?https://github.com/reactiveui/refit
[16]?DelegatingHandler:?https://docs.microsoft.com/en-us/dotnet/api/system.net.http.delegatinghandler?view=netframework-4.8

?

總結(jié)

以上是生活随笔為你收集整理的使用自定义DelegatingHandler编写更整洁的Typed HttpClient的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 色综合天天综合综合国产 | 99国产精品久久久久久久久久久 | 天天综合网在线 | 久在线播放| 9cao| 成人在线观看一区二区三区 | 性欧美日本 | 国产日韩欧美精品在线 | 国内av免费 | av怡红院 | 精品无码av一区二区三区不卡 | 插插插色综合 | 在线看黄网址 | 亚洲天堂成人网 | 亚洲免费一二三区 | 啊v视频在线观看 | 青青精品视频 | 九色在线观看视频 | 精品毛片一区二区三区 | 欧美视频黄色 | 国产精品久久久久久无人区 | 无码人妻精品一区二区三区99不卡 | 男女男精品视频 | 欧美在线另类 | 牛夜精品久久久久久久99黑人 | 亚洲一本在线 | 中文字字幕在线中文乱码 | 国产成人免费看 | 色一情一乱一伦一区二区三区 | 91丨porny丨成人蝌蚪 | 日韩精品成人在线观看 | 国产成人精品123区免费视频 | 国产一级片视频 | 免费看成人aa片无码视频羞羞网 | 国产成人一区二区三区 | 秋霞毛片少妇激情免费 | 熟妇高潮一区二区高潮 | 2019中文在线观看 | √天堂资源地址在线官网 | 日本久久片 | 小毛片网站 | 国产真实夫妇交换视频 | 亚洲va在线 | 日韩欧美国产成人 | 精品黄色片 | 91麻豆国产精品 | 免费网站污 | 免费av影片| 超碰丝袜| 秘密基地在线观看完整版免费 | xxx色 | 绿帽人妻精品一区二区 | 自拍亚洲一区 | 波多野结衣不卡视频 | jizz黄| 国产超碰人人模人人爽人人添 | 亚洲AV成人无码一二三区在线 | 18深夜在线观看免费视频 | 在线国产视频一区 | 献给魔王伊伏洛基亚吧动漫在线观看 | 国产精品99久久久久久久女警 | 国产丰满美女做爰 | 久久久久久久亚洲av无码 | 国产日产久久高清欧美一区 | 日本人の夫妇交换 | 一道本久久 | 中文字幕123区 | 暖暖免费观看日本版 | 久久久久久国 | 日本在线高清视频 | 国产精品久久久久久久毛片 | 诱惑の诱惑筱田优在线播放 | 欧美特级黄色录像 | 免费观看a毛片 | 少妇与公做了夜伦理 | 黄色三级三级三级三级 | 女女同性女同一区二区三区九色 | av鲁丝一区鲁丝二区鲁丝 | 国产精品视频在线免费观看 | 女人被狂躁60分钟视频 | 天天草夜夜操 | 日韩在线精品强乱中文字幕 | 午夜第一页 | 欧美激情一级 | 神马午夜在线观看 | 91视频第一页 | 亚洲人无码成www久久 | 色欲一区二区三区精品a片 在线观看黄网站 | 精品国产乱码一区二区三区99 | 人妻精品久久久久中文字幕 | 欧洲中文字幕日韩精品成人 | 日韩黄色网页 | 亚洲a黄 | 久久精品欧美一区二区 | 阿的白色内裤hd中文 | 男人av影院 | 亚洲国产视频一区二区 | 黄色一级片网站 | 国产精品丝袜视频 |