欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-09-04 13:44:41
使用方式 ihttpclientfactory有四种模式: 基本用法 命名客户端 类型化客户端 生成的客户端 基本用法 在 startup...

使用方式

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));

总结

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