鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > .net技术 > asp.net编程 > >

.Net Core下HTTP请求IHttpClientFactory示例详解

来源:互联网 作者:佚名 时间:2021-09-16 09:21
目录 使用方式 基本用法 命名客户端 类型化客户端 生成的客户端 出站请求中间件 HttpClient和生存周期 使用方式 IHttpClientFactory有四种模式: 基本用法 命名客户端 类型化客户端 生成的客户端 基本用法 在 Startup.ConfigureServices 方法中,通过在 ISer
目录
  • 使用方式
    • 基本用法
    • 命名客户端
    • 类型化客户端
    • 生成的客户端
  • 出站请求中间件
    • HttpClient和生存周期

      使用方式

      IHttpClientFactory有四种模式:

      • 基本用法
      • 命名客户端
      • 类型化客户端
      • 生成的客户端

      基本用法

      在 Startup.ConfigureServices 方法中,通过在 IServiceCollection 上调用 AddHttpClient 扩展方法可以注册 IHttpClientFactory

      services.AddHttpClient();

      注册之后可以像依赖注入DI似得在类中通过构造函数注入形式使用,伪代码:

      class A
      {
       private readonly IHttpClientFactory _clientFactory;
       public A(IHttpClientFactory clientFactory)
       {
        _clientFactory = clientFactory;
       }
       
       Public void Use()
       {
         var request=new HttpRequestMessage(HttpMethod.Get,"www.baidu.com") ;
         var client = _clientFactory.CreateClient();
         var response = await client.SendAsync(request); 
         if (response.IsSuccessStatusCode)
         {
         Branches = await response.Content.ReadAsAsync<IEnumerable<GitHubBranch>>();
         }
        else
        {
         GetBranchesError = true;
         Branches = Array.Empty<GitHubBranch>();
        }  
       }
      }

      命名客户端

      也是在基本用法的基础上增加配置参数:例如增加一个baidu下的客户端:

      services.AddHttpClient("baidu",c=>
      {
       c.BaseAddress = new Uri("https://api.baidu.com/");
       //其他一些参数
      });

      然后在使用的时候只是需要传递客户端名称就自动使用baidu这个地址的基础地址配置:

       var client = _clientFactory.CreateClient("baidu");

      类型化客户端

      说的明白一点就是在使用类的构造函数中可以直接接受HttpClient 类型,不用在使用IHttpClientFactory 接口的CreateClient方法创建,但是首要条件就是要先创建注入类型,然后在ConfigureServices 方法同时注入:

      services.AddHttpClient<classHttp>();

      注入类型:

      public class classHttp
      {
         public HttpClient Client { get; }
         public GitHubService(HttpClient client)
         {
            client.BaseAddress = new Uri("https://api.baidu.com/");
            //同ConfigureServices 中一样设置一些其他参数
            Client = client;
         }
      }

      生成的客户端

      这个我个人理解为就是配置使用第三方库,然后可以注入接口类型,接口中可以写一些方法接口。然后通过接口类直接调用接口。

      个人理解:就是类似于一个接口映射,地址映射似得。通过结合第三方库(官方推荐Refit)实现请求一个地址别名的方式,别名就是指定义的接口。然后别名通过增加特性Get(“路径”)或者post("路径)的形式重新指向真实的请求接口地址。通过请求这个本地接口方法实现转化请求的真实地址。

      举例定义接口:

      public interface IHelloClient
      {
        [Get("/MyInterFace")]
        Task<Reply> GetMessageAsync();
      }

      配置Refit插件:

      也是和正常配置类似,在后面增加接口的服务注入。

      public void ConfigureServices(IServiceCollection services)
      {
        services.AddHttpClient("hello", c =>
        {
          c.BaseAddress = new Uri("http://localhost:5000");
        })
        .AddTypedClient(c => Refit.RestService.For<IHelloClient>(c));
      
        services.AddMvc();
      }

      然后再说接口上面的Get("/MyInterFace")方法;这个我们就不做另一个项目就在当前项目下,所以可以直接就在api项目下创建一个名为MyInterFace的方法。

      [ApiController]
      public class TestController : ControllerBase
      {
         [HttpGet("/")]
        public async Task<sting> MyInterFace()
        {
          return "ceshi";
        }
      }

      然后就可以使用接口了:

      [ApiController]
      public class ValuesController : ControllerBase
      {
        private readonly IHelloClient _client;
      
        public ValuesController(IHelloClient client)
        {
          _client = client;
        }
      
        [HttpGet("/")]
        public async Task<ActionResult<Reply>> Index()
        {
          return await _client.GetMessageAsync();
        }
      }

      在这了的_client.GetMessageAsync()方法就是调用了接口方法,看着是调用了GetMessageAsync方法其实是做了映射,映射地址就是上面特性写的MyInterFace方法。通过断点也可以验证此结论。然后不同项目下也是同一个意思,假如我们请求百度的地址:www.baidu.com/api/b这个接口

      我们在配置出把请求地址http://localhost:5000改为www.baidu.com/api,然后再把GetMessageAsync方法上面的MyInterFace改为b即可。

      出站请求中间件

      个人理解为请求返回前处理程序,就是继承 DelegatingHandler派生类重写SendAsync 方法。在将请求传递至管道中的下一个处理程序之前执行代码:

      public class ValidateHeaderHandler : DelegatingHandler
      {
        protected override async Task<HttpResponseMessage> SendAsync(
          HttpRequestMessage request,
          CancellationToken cancellationToken)
        {
          if (!request.Headers.Contains("X-API-KEY"))
          {
            return new HttpResponseMessage(HttpStatusCode.BadRequest)
            {
              Content = new StringContent(
                "You must supply an API key header called X-API-KEY")
            };
          }
      
          return await base.SendAsync(request, cancellationToken);
        }
      }

      然后在ConfigureServices中:

      services.AddTransient<ValidateHeaderHandler>();//注册处理程序
      services.AddHttpClient("externalservice", c =>
      {
        // Assume this is an "external" service which requires an API KEY
        c.BaseAddress = new Uri("https://localhost:5000/");
      })
      .AddHttpMessageHandler<ValidateHeaderHandler>();/注入到http请求管道

      可以同时注册多个处理程序。

      HttpClient和生存周期

      每次对 IHttpClientFactory 调用 CreateClient 都会返回一个新 HttpClient 实例。 每个命名的客户端都具有一个 HttpMessageHandler。 工厂管理 HttpMessageHandler 实例的生存期。

       HttpClient实例不是与HttpMessageHandler一起销毁的,HttpMessageHandler在池中生存,如果生命周期未到不会被销毁,会被新的HttpClient 实例使用。

      处理程序的默认生存周期是2分钟,可以通过配置修改:

      services.AddHttpClient("extendedhandlerlifetime")
        .SetHandlerLifetime(TimeSpan.FromMinutes(5));

      总结

      以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对鸿网互联的支持。

      网友评论
      <