2016-05-11 23 views
9

Tôi đang sử dụng HttpClient để yêu cầu WebApi.Thực tiễn tốt nhất để sử dụng HttpClient

Tôi đã viết mã này

public async Task<string> ExecuteGetHttp(string url, Dictionary<string, string> headers = null) 
     { 
      using (var client = new HttpClient()) 
      { 
       client.BaseAddress = new Uri(url); 
       client.DefaultRequestHeaders.Accept.Clear(); 
       client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
       if (headers != null) 
       { 
        foreach (var header in headers) 
        { 
         client.DefaultRequestHeaders.Add(header.Key, header.Value); 
        } 
       } 
       var response = await client.GetAsync(url); 
       response.EnsureSuccessStatusCode(); 
       return await response.Content.ReadAsStringAsync(); 
      } 
     } 

Bây giờ tôi gọi phương pháp này từ hành động của tôi.

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

Bây giờ Người ta nói rằng HttpClient has been designed to be re-used for multiple calls.

Tôi có thể sử dụng cùng một đối tượng httpClient cho nhiều cuộc gọi.

Giả sử Đầu tiên tôi gọi

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

Now Trong cùng điều khiển tôi phải gọi một Api với tiêu đề khác nhau và url khác nhau.

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

Tôi có nên làm cho các đối tượng toàn cầu của HttpClient và Sử dụng các đối tượng tương tự cho tất cả các cuộc gọi API.

+0

"Tôi có nên tạo đối tượng chung của HttpClient và Sử dụng cùng một đối tượng cho tất cả các cuộc gọi API không." Tôi cũng tin là vậy. Bạn có thể nghĩ ra bất kỳ lý do cụ thể mà bạn không thể lưu trữ nó trên toàn cầu và tái sử dụng nó cho tất cả các cuộc gọi? – Falgantil

Trả lời

5

Thử thách khi chỉ sử dụng một HttpClient trên ứng dụng là khi bạn muốn sử dụng thông tin xác thực khác hoặc bạn cố thay đổi tiêu đề mặc định cho yêu cầu của mình (hoặc bất kỳ thông tin nào trong số HttpClientHandler được chuyển vào). Trong trường hợp này, bạn sẽ cần một tập hợp các HttpClients mục đích cụ thể để tái sử dụng vì việc sử dụng chỉ là một sẽ có vấn đề.

Tôi khuyên bạn nên tạo một HttpClient cho mỗi "loại" của yêu cầu bạn muốn thực hiện và sử dụng lại chúng. Ví dụ. một cho mỗi thông tin xác thực bạn cần - và có thể nếu bạn có một vài bộ tiêu đề mặc định, mỗi tiêu đề cho mỗi tiêu đề đó.

Nó có thể là một chút của một trò tung hứng giữa các thuộc tính HttpClient (mà không phải là thread an toàn) và cần dụ riêng của họ nếu là đa dạng:

- BaseAddress 
- DefaultRequestHeaders 
- MaxResponseContentBufferSize 
- Timeout 

Và những gì bạn có thể vượt qua vào "ĐỘNG TỪ "phương thức (get, put, post etc). Ví dụ: sử dụng HttpClient.PostAsync Method (String, HttpContent), bạn có thể chỉ định tiêu đề của mình cho [HttpContent][3] (và không phải đặt chúng trong HttpClient DefaultHeaders).

Tất cả các phương pháp async khỏi HttpClient được an toàn (PostAsync) chủ đề, vv

+0

Điều gì về việc tạo HttpRequestMessage cho mỗi yêu cầu? Và sau đó sử dụng phương thức SendAsync của HttpClient. Bằng cách đó bạn có thể chỉ định các thông tin khác nhau giữa các yêu cầu và vẫn sử dụng lại cùng HttpClient. – raRaRa

+0

SendAsync cũng là chủ đề an toàn, vì vậy nó cũng được áp dụng tương tự. – NStuke

5

Chỉ vì bạn có thể, không có nghĩa là bạn nên.

Bạn không phải, nhưng bạn có thể sử dụng lại HttpClient, ví dụ: khi bạn muốn phát hành nhiều yêu cầu HTTP trong vòng lặp chặt chẽ. Điều này tiết kiệm một phần nhỏ thời gian cần thiết để khởi tạo đối tượng.

Bộ điều khiển MVC của bạn được khởi tạo cho mọi yêu cầu. Vì vậy, nó sẽ không gây hại bất kỳ số lượng đáng kể thời gian để khởi tạo một HttpClient cùng một lúc. Hãy nhớ rằng bạn sẽ phát hành một yêu cầu HTTP với nó, điều này sẽ mất nhiều đơn đặt hàng nhiều thời gian hơn so với quá trình instantiation bao giờ hết.

Nếu bạn nhấn mạnh rằng bạn muốn sử dụng lại một cá thể, vì bạn đã đánh giá nó và đánh giá sự khởi tạo của HttpClient là nút cổ chai lớn nhất của bạn, bạn có thể xem tiêm phụ thuộc và tiêm một cá thể vào mỗi bộ điều khiển cần nó.

+0

Điểm tốt ở chỗ bạn cần xem xét trường hợp sử dụng của mình. Nếu bạn cần tối đa hiệu suất tối đa hoặc có mối quan tâm về số lượng kết nối mở, sau đó chia sẻ HttpClients sẽ được hưởng lợi. Khi sử dụng DI, hãy cẩn thận không giải quyết cho mọi cuộc gọi hoặc DI của bạn có thể phủ nhận bất kỳ lợi ích nào. –

+0

@Murray HttpClient sử dụng kết nối tổng hợp. – CodeCaster

+0

Để làm rõ, mọi cá thể HttpClient đều sử dụng nhóm kết nối của riêng nó. –

Các vấn đề liên quan