博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

HttpClient最佳用法

Posted on 2024-07-05 00:38  火冰·瓶  阅读(2)  评论(0编辑  收藏  举报

一、使用IHttpClientFactory创建HttpClient

 

//首先在startup中注册
services.AddHttpClient();
services.AddHttpClient("github", c =>
{
c.BaseAddress = new Uri("https://api.github.com/");
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
});

//然后
public class MyController : Controller
{
    IHttpClientFactory _httpClientFactory;

    public MyController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }


    //Get方法
    public IActionResult Index()
    {
        var client = _httpClientFactory.CreateClient();//一定要通过factory来创建client,不要直接net HttpClient()
        //var client = _httpClientFactory.CreateClient("github");//两种方式都可以
        var result = client.GetStringAsync("http://myurl/");
        return View();
    }
//Post方法
public IActionResult Index2()
{
  var client = _httpClientFactory.CreateClient(); //一定要通过factory来创建client,不要直接net HttpClient()
      //var client = _httpClientFactory.CreateClient("github");//两种方式都可以
  client.BaseAddress = new Uri(baseAddress);
  client.DefaultRequestHeaders.TryAddWithoutValidation("App-Key", "xxx");
  client.DefaultRequestHeaders.TryAddWithoutValidation("App-Sign", "xxx");

  var jsonData = new
  {
  seqid = Guid.NewGuid().ToString(),
  provCode = "510000",
  cityCode = "513300",
  };

  string jsonDataStr = JsonSerializer.Serialize(jsonData); //序列化为字符串
  string url = "/url/xxx/xxx"; //接口url
  HttpContent content = new StringContent(jsonDataStr, Encoding.UTF8, "application/json");
  HttpResponseMessage response = await _client.PostAsync(url, content);
  string responseBody = response.Content.ReadAsStringAsync().Result; //返回值 

return View();
}
}
}

 

  

 

  

二、使用Send和HttpRequestMessage

//创建一个静态HttpClient
    public  class HttpClientFactory
    {
        private static SocketsHttpHandler socketsHttpHandler = new SocketsHttpHandler()
        {
            AllowAutoRedirect = true,//是否自动重定向
            MaxAutomaticRedirections = 50,//自动重定向的最大次数
            UseCookies = false,// 是否自动处理cookie               
            MaxConnectionsPerServer = 100,//每个请求连接的最大数量,默认是int.MaxValue,可以认为是不限制
            PooledConnectionIdleTimeout = TimeSpan.FromMinutes(2),//连接池中TCP连接最多可以闲置多久,默认2分钟
            //PooledConnectionLifetime = Timeout.InfiniteTimeSpan,//连接最长的存活时间,默认是不限制的,一般不用设置           
            //ConnectTimeout = Timeout.InfiniteTimeSpan,//建立TCP连接时的超时时间,默认不限制
            //Expect100ContinueTimeout = TimeSpan.FromSeconds(1),//等待服务返回statusCode=100的超时时间,默认1秒
            //MaxResponseHeadersLength = 64, //响应头数据大小限制;一般不用设置,单位: KB
        };
private static readonly HttpClient _httpClient = new HttpClient(socketsHttpHandler); public static HttpClient Client { get { return _httpClient; } } } //使用HttpClient的位置 var jsonData = new { seqid = Guid.NewGuid().ToString(), provCode="510000" //省 }; string jsonDataStr = JsonSerializer.Serialize(jsonData); HttpContent content = new StringContent(jsonDataStr, Encoding.UTF8, "application/json"); HttpRequestMessage msg = new HttpRequestMessage { Method = HttpMethod.Post, RequestUri = new Uri(baseAddress + url), Content = content }; msg.Headers.TryAddWithoutValidation("App-Key", "xxx"); msg.Headers.TryAddWithoutValidation("App-Sign", "xxx"); HttpClient _client = HttpClientFactory.Client; HttpResponseMessage response = await _client.SendAsync(msg); //使用Send方法发起请求,如果使用Post方法,改变HttpClient的BaseAddress或其他属性时,会抛异常“This instance has already started httpclient...........” string responseBody = response.Content.ReadAsStringAsync().Result;

 

 

三、stackoverflow上的建议

//Better to add the request url and the headers at the message. Don't use httpClient.BaseAddress or httpClient.DefaultRequestHeaders unless you have a default requirement.

HttpRequestMessage msg = new HttpRequestMessage {
    Method = HttpMethod.Put,
    RequestUri = new Uri(url),
    Headers = httpRequestHeaders;
};

httpClient.SendAsync(msg);

  

//If you don't have consistent defaults then BaseAddress and DefaultRequestHeaders should not be used. Create a new HttpRequestMessage instead:

        var incoming = new Uri(uri, UriKind.Relative); // Don't let the user specify absolute urls.
        var outgoing = new Uri(new Uri("http://example.com/"), incoming);
        var request = new HttpRequestMessage(HttpMethod.Get, outgoing);
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        var response = await _client.SendAsync(request);

  

//It's preferable to add the url of your request and the headers at the message, rather than on the client. better not to use the BaseAddress or DefaultRequestHeaders unless you have have to.

HttpRequestMessage yourmsg = new HttpRequestMessage {
    Method = HttpMethod.Put,
    RequestUri = new Uri(url),
    Headers = httpRequestHeaders;
};


httpClient.SendAsync(yourmsg);