2017-04-24 16 views
0

아래 코드 조각에서 DelegatingHandler를 구현하려고합니다. 당신은 ... 나는 InnerHandler에 요청을 전달하는 기존의 관행에서 일탈하고있는가 SendAsync 방법에DelegatingHandler에서 HttpClient를 사용할 때 오류 : 요청 메시지가 이미 전송되었습니다. 동일한 요청 메시지를 여러 번 보낼 수 없습니다.

base.SendAsync(request, cancellationToken); 

을 것을 알 수 있습니다 ... 대신 HttpClient를의 새로운 인스턴스, 내가 지나가는 오전 만드는 오전 요청 :이이 같은 노출 된 뼈 조각에 생소 할 수 있습니다

new HttpClient().SendAsync(request, cancellationToken); 

, 그러나 여기에서 아이디어는 특정 조건에 따라 다른 HttpClientHandlers에 요청을 전달하는 것입니다, 그래서를 인스턴스화 할 수 있어야합니다 동적으로 HttpClient. 나는 다음과 같은 예외가이 코드를 실행하면

그러나, 누군가가 나에게 무엇을 원인과 무엇을 이해하는 데 도움 주실 래요

The request message was already sent. Cannot send the same request message multiple times. 

는 (짧은 내 요구 사항을 구현하는 더 나은 방법이 될 것입니다 전달하는 것보다는 핸들러에서 요청을 복제하는 것이 효과적이지만 우아하지는 않습니다).

using System; 
using System.Net.Http; 
using System.Threading; 
using System.Threading.Tasks; 

namespace DelegatingHandlerTest 
{ 
    internal static class Program 
    { 
     private static void Main() 
     { 
      var httpClient = new HttpClient(new MyTestHandler()); 

      var response = httpClient.GetAsync("http://icanhazip.com/").Result; 

      Console.WriteLine(response.Content.ReadAsStringAsync().Result); 
     } 

    private class MyTestHandler : DelegatingHandler 
    { 

     protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
     { 
      return await new HttpClient().SendAsync(request, cancellationToken); 
     } 

    } 
} 
+0

HttpClient를의 소스 코드를 보면, 지금 참조 src/System/Net/Http/HttpClient.cs # L599 내 코드처럼 요청이 HttpClient의 두 인스턴스를 통과하게 만듭니다. 첫 번째 사람이 보자 마자 보내진 것으로 표시하고 그 시간까지 두 번째로 도착하면 벌써 손상된 물건입니다. 해결 방법을 찾는데 도움이 필요합니다. 단순히 요청을 복제하는 것이 문제를 다루는 바보 같은 방법처럼 보입니다. –

답변

0

DelagatingHandler에는 내부 처리기가 필요하므로 거기에 요청 처리기 인스턴스를 전달해야합니다.

private static void Main() 
{ 
     var httpClient = new HttpClient(new MyTestHandler(new HttpClientHandler())); 

     var response = httpClient.GetAsync("http://icanhazip.com/").Result; 

     Console.WriteLine(response.Content.ReadAsStringAsync().Result); 
} 


private class MyTestHandler : DelegatingHandler 
{ 

     public MyTestHandler(HttpClientHandler handler) { 
      base.InnerHandler = handler; 
     } 

     protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
     { 
      return await base.SendAsync(request, cancellationToken); 
     } 

} 
+0

@ andym1978 감사합니다. 그러나 게시 한 응답은 기본 클래스의 SendAsync 메서드를 호출하는 예입니다.이 때문에 생성자에서 내부 처리기를 정의해야합니다. 이 질문에서 언급했듯이 SendAsync 재정의에서 HttpClient의 새 인스턴스를 만드는 유연성이 필요합니다.이 경우 내부 처리기가 호출되지 않습니다. 도움을 주신 것에 대해 다시 한 번 감사드립니다. –

0

나는 당신의 요구 사항을 오해 할 수 있지만 당신은 단지 다양한 핸들러 사이에서 결정해야하는 경우가 base.SendAsync를 호출하기 전에 InnerHandler에 대한 적절한 HttpClientHandler를 할당 할 수 없습니다()? https://github.com/dotnet/corefx/blob/master/src/System.Net.Http/ :이 같은 예외가 어디에서 오는지

private class MyTestHandler : DelegatingHandler 
{ 

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 

     if (someCondition) 
     { 
      base.InnerHandler = new MyHttpClientHandler(...); 
     } 

     else 
     { 
      base.InnerHandler = new MyOtherHttpClientHandler(...); 
     } 

     return await base.SendAsync(request, cancellationToken); 

    } 

} 
+0

매우 안전하지 않은 스레드 ... – Tratcher