2018-09-18html
core 2.1 以後有新的方案咯web
http://www.talkingdotnet.com/3-ways-to-use-httpclientfactory-in-asp-net-core-2-1/api
就是解決以前單列等等的問題.安全
給個例子 服務器
定義一個 serviceasync
public class ServerTaskHttpClient { public HttpClient Client { get; private set; } public ServerTaskHttpClient( HttpClient httpClient, IConfiguration configuration ) { httpClient.BaseAddress = new Uri(configuration["Origin"] + "/api"); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json));
// httpClient.DefaultRequestHeaders.Add(HeaderNames.ContentType, MediaTypeNames.Application.Json); //注意, 放這裏是錯的, content-type 不是這裏 set 的,而是經過 content Client = httpClient; } }
startup.cs ide
加入依賴 providers學習
services.AddHttpClient<ServerTaskHttpClient>();
在 controller 調用this
public class ResponseData { public bool successful { get; set; } } public async Task<IActionResult> Index() { var content = new StringContent(JsonConvert.SerializeObject(new { name = "dada" }), Encoding.UTF8, MediaTypeNames.Application.Json); var result = await ServerTaskHttpClient.Client.PostAsync("/api/debug/clearImage", content); if (result.IsSuccessStatusCode) { var responseData = JsonConvert.DeserializeObject<ResponseData>(await result.Content.ReadAsStringAsync()); } return View(); }
api spa
[HttpPost("clearImage")] public async Task<IActionResult> ClearImage(Data data) { return Ok(new { successful = true }); }
2017-09-25
core 和 .net 4.5 同樣均可以使用 HttpClient
沒什麼特別的, 只是在學習的時候發現一個以前沒留意到的問題.
refer :
https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
http://byterot.blogspot.my/2016/07/singleton-httpclient-dns.html
http://www.cnblogs.com/dudu/p/csharp-httpclient-attention.html
https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client
http://www.cnblogs.com/Wddpct/p/6229090.html
大體上說的是, HttpClient 不要使用 using, 由於它並不會釋放 TCP 鏈接, 應該在整個應用裏把 HttpClient 設置成單列
core 要設置單列對象很容易
public class VisautoHttpClient : HttpClient { public VisautoHttpClient() { BaseAddress = new Uri("http://visauto.stooges.com.my"); Timeout = TimeSpan.FromSeconds(30); DefaultRequestHeaders.Clear(); DefaultRequestHeaders.Add("Accept", "text/html"); DefaultRequestHeaders.Connection.Add("Keep-Alive"); } }
定義好類, 因爲每一個 TCP 的 baseAddress 不能換的,因此若是你有不少個不一樣區的請求要發, 那麼建議開多幾個 HttpClient 實例.
keep-alive 的目的是讓服務端知道咱們的鏈接不要立刻斷開, 這樣發多個請求的話能夠快一些.
而後在 startup.cs 提供服務就能夠了.
public void ConfigureServices(IServiceCollection services) { // services services.AddSingleton<VisautoHttpClient, VisautoHttpClient>(); }
core 會幫咱們搞定 singleton 的線程安全等問題. 不須要像從前還要用 lock 什麼的那麼麻煩了.
並且這裏只是定義,一直到控制器注入時纔會初始化實例哦.
在控制器注入了就能夠發請求咯~
[Area("Web")] public class HttpController : Controller { public HttpController( VisautoHttpClient httpClient ) { this.httpClient = httpClient; } private HttpClient httpClient { get; set; } [Route("http")] public async Task<IActionResult> Index() { try { string x = await httpClient.GetStringAsync(""); } catch (Exception ex) { } return View(); } }
note : 若是服務器 restart, 咱們的鏈接並不須要任何處理, 都是自動的. 放心, dns 的問題我沒有遇到, 遇到了纔打算唄.