使用HttpClient的最佳实践

时间:2016-05-11 08:34:03

标签: c# asp.net asp.net-mvc asp.net-web-api

我正在使用HttpClient向WebApi发出请求。

我写了这段代码

public async Task<ActionResult> Index()
        {
            try
            {
                RestWebRequest RestWebRequest = new RestWebRequest();
                Dictionary<string, string> headers = new Dictionary<string, string>();
                headers.Add("Authorization", "bearer _AxE9GWUO__8iIGS8stK1GrXuCXuz0xJ8Ba_nR1W2AhhOWy9r98e2_YquUmjFsAv1RcI94ROKEbiEjFVGmoiqmUU7qB5_Rjw1Z3FWMtzEc8BeM60WuIuF2fx_Y2FNTE_6XRhXce75MNf4-i0HbygnClzqDdrdG_B0hK6u2H7rtpBFV0BYZIUqFuJpkg4Aus85P8_Rd2KTCC5o6mHPiGxRl_yGFFTTL4_GvSuBQH39RoMqNj94A84KlE0hm99Yk-8jY6AKdxGRoEhtW_Ddow9FKWiViSuetcegzs_YWiPMN6kBFhY401ON_M_aH067ciIu6nZ7TiIkD5GHgndMvF-dYt3nAD95uLaqX6t8MS-WS2E80h7_AuaN5JZMOEOJCUi7z3zWMD2MoSwDtiB644XdmQ5DcJUXy_lli3KKaXgArJzKj85BWTAQ8xGXz3PyVo6W8swRaY5ojfnPUmUibm4A2lkRUvu7mHLGExgZ9rOsW_BbCDJq6LlYHM1BnAQ_W6LAE5P-DxMNZj7PNmEP1LKptr2RWwYt17JPRdN27OcSvZZdam6YMlBW00Dz2T2dgWqv7LvKpVhMpOtjOSdMhDzWEcf6yqr4ldVUszCQrPfjfBBtUdN_5nqcpiWlPx3JTkx438i08Ni8ph3gDQQvl3YL5psDcdwh0-QtNjEAGvBdQCwABvkbUhnIQQo_vwA68ITg07sEYgCl7Sql5IV7bD_x-yrlHyaVNtCn9C4zVr5ALIfj0YCuCyF_l1Z1MTRE7nb");
                var getCategories = await RestWebRequest.ExecuteGetHttp("http://localhost:53646/api/Job/GetAllCategories?isIncludeChild=true", headers);
            }
            catch (HttpRequestException ex)
            {
                return View();
            }
  return View();
  }

现在我从我的行动中调用这个方法。

http://localhost:53646/api/Job/GetAllCategories?isIncludeChild=true

现在据说 HttpClient has been designed to be re-used for multiple calls

如何为多个调用使用相同的httpClient对象。

我们假设 首先我要打电话

http://localhost:53646/api/Job/category/10

现在在同一个控制器中,我必须使用不同的标题和不同的URL来调用另一个Api。

HttpClient

我应该创建{{1}}的全局对象,并为所有API调用使用相同的对象。

3 个答案:

答案 0 :(得分:8)

在整个应用程序中仅使用一个HttpClient的挑战是,您希望使用不同的凭据,或者尝试更改请求的默认标头(或传入的HttpClientHandler中的任何内容)。在这种情况下,您将需要一组特定目的的HttpClient来重复使用,因为只使用一个会有问题。

我建议按照&#34;类型&#34;创建一个HttpClient。您希望制作并重复使用的请求。例如。一个用于您需要的每个凭证 - 如果您有几组默认标题,则每个凭证一个。

它可能是HttpClient属性(不是线程安全的)之间的一种杂耍行为,如果变化则需要它们自己的实例:

- BaseAddress
- DefaultRequestHeaders
- MaxResponseContentBufferSize
- Timeout

你可以传递给&#34; VERB&#34;方法(获取,放置,发布等)。例如,使用HttpClient.PostAsync Method (String, HttpContent),您可以为[HttpContent][3]指定标题(而不必将它们放在HttpClient DefaultHeaders中)。

HttpClient的所有Async方法都是线程安全的(PostAsync)等。

答案 1 :(得分:6)

仅仅因为你可以,并不意味着你应该。

不必,但可以重用HttpClient,例如,当您想要在紧密循环中发出许多HTTP请求时。这节省了实例化对象所花费的一小部分时间。

您的MVC控制器会针对每个请求进行实例化。因此,同时实例化HttpClient不会损害任何大量的时间。请记住,您将使用它发出HTTP请求,这将比实例化更多的时间。

如果你坚持要重用一个实例,因为你已经对它进行了基准测试并评估了HttpClient的实例化是你最大的瓶颈,那么你可以看看依赖注入并将一个实例注入到需要的每个控制器中它

答案 2 :(得分:1)

.net核心中,您可以对 HttpClientFactory 进行以下操作:

public interface IBuyService
{
    Task<Buy> GetBuyItems();
}

public class BuyService: IBuyService
{
    private readonly HttpClient _httpClient;

    public BuyService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<Buy> GetBuyItems()
    {
        var uri = "Uri";

        var responseString = await _httpClient.GetStringAsync(uri);

        var buy = JsonConvert.DeserializeObject<Buy>(responseString);
        return buy;
    }
}

ConfigureServices

services.AddHttpClient<IBuyService, BuyService>(client =>
{
     client.BaseAddress = new Uri(Configuration["BaseUrl"]);
});

herehere上的文档和示例