在许多时候我们在差异的处事之间需要通过HttpClient举办实时通讯,在我们的代码中我们会建设本身的HttpClient工具然后去跨规模额举办数据的交互,可是往往由于一个项目有多小我私家开拓所以在开拓中没有人常常会因为差异的业务请求去写差异的代码,然后就会造成各类气势气魄的HttpClient的跨域请求,最重要的是由于每小我私家对HttpClient的领略水平差异所以写出来的代码大概质量上会有东倒西歪,纵然代码可以或许到达要求往往也显得很是臃肿,反复高我们在正式先容Refit这个项目之前,我们来看看我们在项目中常用的挪用方法,后头再来先容这种处理惩罚方法的漏洞以及后头集成了Refit今后我们代码的质量可以或许有哪些水平的提高。
一 通例建设方法在通例的方法中我们一般利用IHttpClientFactory来建设HttpClient工具,然后利用这个工具来发送和吸收动静,至于为什么要利用这个接口来建设HttpClient工具而不是利用using new HttpClient的原因请点击这里相识更多的信息,我们先来看下面的这个例子。
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using System.Web; using Abp.Domain.Services; using Microsoft.Extensions.Logging; using Newtonsoft.Json; namespace Sunlight.Dms.Parts.Domain.Web { /// <summary> /// HttpClient的辅佐类 /// </summary> public class DcsPartClientService : DomainService { private readonly HttpClient _httpClient; private readonly ILogger<DcsPartClientService> _loggerHelper; public DcsPartClientService(IHttpClientFactory httpClientFactory, ILogger<DcsPartClientService> loggerHelper) { _loggerHelper = loggerHelper; _httpClient = httpClientFactory.CreateClient(PartsConsts.DcsPartClientName); if (_httpClient.BaseAddress == null) { throw new ArgumentNullException(nameof(httpClientFactory), $"没有设置名称为 {PartsConsts.DcsPartClientName} 的HttpClient,可能接口处事的地点为空"); } } /// <summary> /// Post请求返回实体 /// </summary> /// <param>请求相对路径</param> /// <param>请求数据</param> /// <returns>实体T</returns> public async Task<List<T>> PostResponse<T>(string relativeUrl, object postObj) where T : class { var postData = JsonConvert.SerializeObject(postObj); _httpClient.DefaultRequestHeaders.Add("user-agent", "Dcs-Parts"); _httpClient.CancelPendingRequests(); _httpClient.DefaultRequestHeaders.Clear(); HttpContent httpContent = new StringContent(postData); httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var result = default(List<T>); var response = await _httpClient.PostAsync(_httpClient.BaseAddress + relativeUrl, httpContent); if (response.StatusCode == HttpStatusCode.NotFound) { throw new ValidationException("找不到对应的DcsParts处事"); } var responseContent = await response.Content.ReadAsAsync<ReceiveResponseBody<List<T>>>(); if (response.IsSuccessStatusCode) { result = responseContent?.Payload; } else { if (!string.IsNullOrWhiteSpace(responseContent?.Message)) { throw new ValidationException(responseContent.Message); } _loggerHelper.LogDebug($"请求返回功效:{0} 请求内容:{1}", response.StatusCode, postData); } return await Task.FromResult(result); } public async Task<List<T>> GetResponse<T>(string relativeUrl, object queryObj) where T : class { var queryData = ModelToUriQueryParam(queryObj); _httpClient.DefaultRequestHeaders.Add("user-agent", "Dcs-Parts"); _httpClient.CancelPendingRequests(); _httpClient.DefaultRequestHeaders.Clear(); _httpClient.DefaultRequestHeaders.Add("accept", "application/json"); var result = default(List<T>); var response = await _httpClient.GetAsync(_httpClient.BaseAddress + relativeUrl + queryData); if (response.StatusCode == HttpStatusCode.NotFound) { throw new ValidationException("找不到对应的DcsParts处事"); } var responseContent = await response.Content.ReadAsAsync<ReceiveResponseBody<List<T>>>(); if (response.IsSuccessStatusCode) { result = responseContent?.Payload; } else { if (!string.IsNullOrWhiteSpace(responseContent?.Message)) { throw new ValidationException(responseContent.Message); } } return await Task.FromResult(result); } private string ModelToUriQueryParam<T>(T t, string url = "") { var properties = t.GetType().GetProperties(); var sb = new StringBuilder(); sb.Append(url); sb.Append("?"); foreach (var p in properties) { var v = p.GetValue(t, null); if (v == null) continue; sb.Append(p.Name); sb.Append("="); sb.Append(HttpUtility.UrlEncode(v.ToString())); sb.Append("&"); } sb.Remove(sb.Length - 1, 1); return sb.ToString(); } } public class ReceiveResponseBody<T> where T : class { public string Message { get; set; } public T Payload { get; set; } } public class ReceiveResponseBody { public string Message { get; set; } } }
1.1 注入IHttpClientFactory工具