首页 > 技术文章 > .net core 5.0 之IHttpClientFactory

roubaozidd 2022-03-21 15:27 原文

官网介绍:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/http-requests?view=aspnetcore-5.0

引入NuGet包(涉及到策略才引用)

Microsoft.Extensions.Http.Polly

 

appsettings.json:

 "Services": {
    "userapi": "http://192.168.0.236:7202",
    "fileapi": "http://192.168.0.236:7205",
     "conv19vaccineapi": "http://192.168.0.236:7410"
  },

  

Startup:

IConfigurationSection section = Configuration.GetSection("Services");
            List<string> list = new List<string>();
            var childes = section.GetChildren();
            foreach (var configSection in childes)
            {

                var conKey = configSection.Key;

            }
            var serviceList = Configuration.GetSection("Services").GetChildren();
            var fallbackResponse = new HttpResponseMessage
            {
                Content = new StringContent("服务器内部错误"),
                StatusCode = HttpStatusCode.RequestTimeout
            };
            foreach (ConfigurationSection configSection in serviceList)
            {
                services.AddHttpClient(configSection.Key, async (provider, client) =>
                {
                    var httpcontextaccessor = provider.GetService<IHttpContextAccessor>();
                    var token = await httpcontextaccessor.HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken);
                    client.BaseAddress = new Uri(configSection.Value);
                    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
                    client.DefaultRequestHeaders.Add("X-ClientIP", httpcontextaccessor.HttpContext.Connection.RemoteIpAddress?.ToString());
                })
                 //异常
                 .AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>()
                 //快速反馈
                 .FallbackAsync(fallbackResponse, async b =>
                 {

                     await Task.CompletedTask;

                 }))
                  // 重试
                  .AddPolicyHandler(Policy<HttpResponseMessage>
                    .Handle<TimeoutRejectedException>()
                    .WaitAndRetryAsync(
                        new[]
                        {
                          TimeSpan.FromMilliseconds(100),
                          TimeSpan.FromMilliseconds(200)
                        }
                    )
                  )
                    // 超时
                    .AddPolicyHandler(
                    Policy.TimeoutAsync<HttpResponseMessage>(
                        TimeSpan.FromSeconds(180)
                        )
                      );

            }

控制器调用

public class BaseController : Controller
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IHttpClientFactory _httpClientFactory;

        public BaseController(IHttpContextAccessor httpContextAccessor, IHttpClientFactory httpClientFactory)
        {
            _httpContextAccessor = httpContextAccessor;
            _httpClientFactory = httpClientFactory;
        }
        /// <summary>
        /// 公共Post请求方法
        /// </summary>
        /// <param name="servciesname">服务名称</param>
        /// <param name="url">服务地址</param>
        /// <param name="json">数据</param>
        /// <returns></returns>
        protected async Task<IActionResult> ClientPostAsync(string servciesname, string url, object json)
        {

            //var token = await GetTokenAsync();
            //if (string.IsNullOrEmpty(token))
            //{
            //    throw new Exception("登录信息过期,请重新登录");
            //}
            using (var _httpClient = _httpClientFactory.CreateClient(servciesname))
            {
                url = _httpClient.BaseAddress + url;
                // _httpClient.SetBearerToken(token);
                var response = await _httpClient.PostAsJsonAsync(url, json);
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    var result = await response.Content.ReadAsStringAsync();
                    return Ok(result);
                }
                else if (response.StatusCode == HttpStatusCode.Unauthorized)
                {

                    return Ok(new { Result = 401, Message = "登录信息已经过期,请重新登录" });
                }
                return Ok(new { Result = 404, Message = "数据请求失败" });
            }
           
            
        }

        protected async Task<string> ClientPostResultStringAsync(string servciesname, string url, object json)
        {

            //var token = await GetTokenAsync();
            //if (string.IsNullOrEmpty(token))
            //{
            //    throw new Exception("登录信息过期,请重新登录");
            //}
            using (var _httpClient = _httpClientFactory.CreateClient(servciesname))
            {
                url = _httpClient.BaseAddress + url;
                // _httpClient.SetBearerToken(token);
                var response = await _httpClient.PostAsJsonAsync(url, json);
                if (response.StatusCode == HttpStatusCode.OK)
                    return response.Content.ReadAsStringAsync().Result;
                return "";
            }
            
        }
        /// <summary>
        /// Get请求
        /// </summary>
        /// <param name="servicesname"></param>
        /// <param name= "url"></param>
        /// <returns></returns>
        protected async Task<IActionResult> ClientGetAsync(string servicesname, string url)
        {
            //var token = await GetTokenAsync();
            //if (string.IsNullOrEmpty(token))
            //{
            //    throw new Exception("登录信息过期,请重新登录");
            //}
            try
            {
                using (var _httpClient = _httpClientFactory.CreateClient(servicesname))
                {
                    
                    url = _httpClient.BaseAddress + url;
                    // _httpClient.SetBearerToken(token);

                    var response = await _httpClient.GetAsync(url);
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        var result = await response.Content.ReadAsStringAsync();
                        return Ok(result);
                    }
                    else if (response.StatusCode == HttpStatusCode.Unauthorized)
                    {

                        return Ok(new { Result = 401, Message = "登录信息已经过期,请重新登录" });
                    }
                    return Ok(new { Result = 404, Message = "数据请求失败" });
                }
                
            }
            catch (Exception e)
            {
                return Ok(new { Result = 404, Message = "数据请求失败" });
            }

        }

        /// <summary>
        /// Delete请求
        /// </summary>
        /// <param name="servicesname"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        protected async Task<IActionResult> ClientDeleteAsync(string servicesname, string url)
        {
            // var token = await GetTokenAsync();
            //if (string.IsNullOrEmpty(token))
            //{
            //    throw new Exception("登录信息过期,请重新登录");
            //}
            using (var _httpClient = _httpClientFactory.CreateClient(servicesname))
            {
                url = _httpClient.BaseAddress + url;
                //   _httpClient.SetBearerToken(token);
                var response = await _httpClient.DeleteAsync(url);
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    return Ok(response.Content.ReadAsStringAsync().Result);
                }
                else if (response.StatusCode == HttpStatusCode.Unauthorized)
                {

                    return Ok(new { Result = 401, Message = "登录信息已经过期,请重新登录" });
                }
                return Ok(new { Result = 404, Message = "数据请求失败" });
            }
            
           

        }
        /// <summary>
        /// Put请求
        /// </summary>
        /// <param name="servicesname"></param>
        /// <param name="url"></param>
        /// <param name="json"></param>
        /// <returns></returns>
        protected async Task<IActionResult> ClientPutAsync(string servicesname, string url, object json)
        {
            //var token = await GetTokenAsync();
            //if (string.IsNullOrEmpty(token))
            //{
            //    throw new Exception("登录信息过期,请重新登录");
            //}
            using (var _httpClient = _httpClientFactory.CreateClient(servicesname))
            {
                
                url = _httpClient.BaseAddress + url;
                //   _httpClient.SetBearerToken(token);
                var response = await _httpClient.PutAsJsonAsync(url, json);
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    var result = await response.Content.ReadAsStringAsync();
                    return Ok(result);
                }
                else if (response.StatusCode == HttpStatusCode.Unauthorized)
                {

                    return Ok(new { Result = 401, Message = "登录信息已经过期,请重新登录" });
                }
                return Ok(new { Result = 404, Message = "数据请求失败" });
            }
            

        }

        /// <summary>
        /// Post文件传输
        /// </summary>
        /// <param name="servicesname"></param>
        /// <param name="url"></param>
        /// <param name="file"></param>
        /// <returns></returns>
        protected async Task<IActionResult> ClientPostFileAsync(string servicesname, string url, IFormFile file)
        {
            using (var _httpClient = _httpClientFactory.CreateClient(servicesname))
            {
                url = _httpClient.BaseAddress + url;

                var stream = file.OpenReadStream();

                var httpContent = new MultipartFormDataContent();
                httpContent.Add(new StreamContent(stream), "file", file.FileName);

                var response = await _httpClient.PostAsync(url, httpContent);
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    var result = await response.Content.ReadAsStringAsync();
                    return Ok(result);
                }
                else if (response.StatusCode == HttpStatusCode.Unauthorized)
                {

                    return Ok(new { Result = 401, Message = "登录信息已经过期,请重新登录" });
                }
                return Ok(new { Result = 404, Message = "数据请求失败" });
            }
            
            
        }
    }

  

 

推荐阅读