HttpClient 正确使用方法
如何 正确模拟 Http请求,建议使用HttpClient
错误用法
var httpClient=new HttpClient();
正确用法
1 | ServiceCollection.AddHttpClient(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | public class Http: IHttp { private readonly IHttpClientFactory _httpClientFactory; private readonly IJsonContext _jsonContext; public Http(IServiceContext serviceContext) { _jsonContext = serviceContext.GetRequiredService<IJsonContext>(); _httpClientFactory = serviceContext.GetRequiredService<IHttpClientFactory>(); } public async Task<TResponse> ExecuteAsync< TResponse>(HttpTypeEnum httpType, string url, Dictionary< string , string >? headers = null , CancellationToken cancellationToken = default ) { try { var httpClient = _httpClientFactory.CreateClient(); HttpMethod httpMethod = httpType switch { HttpTypeEnum.Get => HttpMethod.Get, HttpTypeEnum.Patch => HttpMethod.Get, HttpTypeEnum.Post => HttpMethod.Get, HttpTypeEnum.Put => HttpMethod.Get, HttpTypeEnum.Delete => HttpMethod.Get, _ => HttpMethod.Get, }; var httpRequestMessage = new HttpRequestMessage(httpMethod, url); if (headers != null ) { foreach ( var header in headers) { httpRequestMessage.Headers.Add(header.Key, header.Value); } } httpClient.Timeout = TimeSpan.FromSeconds(120); var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage, cancellationToken); if (httpResponseMessage.IsSuccessStatusCode) { var responseJson = await httpResponseMessage.Content.ReadAsStringAsync(cancellationToken); var response = _jsonContext.Deserialize<TResponse>(responseJson); if (response is null ) { throw new GrowHttpException($ "接口请求错误,序列化错误 {responseJson}" ); } return response; } else { throw new GrowHttpException($ "接口请求错误,错误代码{httpResponseMessage.StatusCode},错误原因{httpResponseMessage.ReasonPhrase}" ); } } catch (GrowHttpException ex) { throw ex; } catch (Exception ex) { throw new GrowHttpException($ "客户端调用异常:{ex.Message},接口地址:{url},调用堆栈{ex.StackTrace}" ); } } public async Task<TResponse> ExecuteAsync<TRequest, TResponse>(HttpTypeEnum httpType, string url, TRequest request, Dictionary< string , string >? headers= null , CancellationToken cancellationToken = default ) { try { if (request is null ) { throw new GrowHttpException($ "接口请求错误, {nameof(request)} is null" ); } var requestJson = _jsonContext.Serialize(request); if (requestJson is null ) { throw new GrowHttpException($ "接口请求错误,序列化错误 {nameof(request)}" ); } var httpClient = _httpClientFactory.CreateClient(); HttpMethod httpMethod = httpType switch { HttpTypeEnum.Get => HttpMethod.Get, HttpTypeEnum.Patch => HttpMethod.Get, HttpTypeEnum.Post => HttpMethod.Get, HttpTypeEnum.Put => HttpMethod.Get, HttpTypeEnum.Delete => HttpMethod.Get, _ => HttpMethod.Get, }; var httpRequestMessage = new HttpRequestMessage(httpMethod, url); if (headers != null ) { foreach ( var header in headers) { httpRequestMessage.Headers.Add(header.Key, header.Value); } } httpRequestMessage.Content = new StringContent(requestJson); httpClient.Timeout = TimeSpan.FromSeconds(120); var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage, cancellationToken); if (httpResponseMessage.IsSuccessStatusCode) { var responseJson = await httpResponseMessage.Content.ReadAsStringAsync(cancellationToken); var response = _jsonContext.Deserialize<TResponse>(responseJson); if (response is null ) { throw new GrowHttpException($ "接口请求错误,序列化错误 {responseJson}" ); } return response; } else { throw new GrowHttpException($ "接口请求错误,错误代码{httpResponseMessage.StatusCode},错误原因{httpResponseMessage.ReasonPhrase}" ); } } catch (GrowHttpException ex) { throw ex; } catch (Exception ex) { throw new GrowHttpException($ "客户端调用异常:{ex.Message},接口地址:{url},调用堆栈{ex.StackTrace}" ); } } } |
通过依赖注入 通过IHttpClientFactory 使用连接池复用HttpClient
我不是代码的生产者,只是代码的搬运工
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构