2017-02-19 11 views
1

Web API 2アプリケーションでHEAD要求を処理したい。私はコピー&ペーストStrathWebのブログ記事Adding HTTP HEAD support to ASP.NET Web APIからコード:Web API 2でHEAD要求を処理するときのContent-Length 0

public class HeadHandler : DelegatingHandler 
{ 
    private const string Head = "IsHead"; 

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) 
    { 
     if (request.Method == HttpMethod.Head) 
     { 
      request.Method = HttpMethod.Get; 
      request.Properties.Add(Head, true); 
     } 

     var response = await base.SendAsync(request, cancellationToken); 

     object isHead; 
     response.RequestMessage.Properties.TryGetValue(Head, out isHead); 

     if (isHead != null && ((bool) isHead)) 
     { 
      var oldContent = await response.Content.ReadAsByteArrayAsync(); 
      var content = new StringContent(string.Empty); 
      content.Headers.Clear(); 

      foreach (var header in response.Content.Headers) 
      { 
       content.Headers.Add(header.Key, header.Value); 
      } 

      content.Headers.ContentLength = oldContent.Length; 
      response.Content = content; 
     } 

     return response; 
    } 
} 

私はフィドラーからのHEADリクエスト作るとき:

HEAD http://localhost:54225/api/books/5 HTTP/1.1 
User-Agent: Fiddler 
Host: localhost:54225 

を、私は戻って、次の応答を取得:

HTTP/1.1 200 OK 
Cache-Control: no-cache 
Pragma: no-cache 
Content-Length: 0 
Content-Type: application/json; charset=utf-8 
Expires: -1 
Server: Microsoft-IIS/10.0 
X-AspNet-Version: 4.0.30319 
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcc2ltb25lXERvY3VtZW50c1xTaW1vbnNEb2N1bWVudHNcSVRcQyNcRGVtb0NvZGVcUkVTVGZ1bFdlYlNlcnZpY2VDbGllbnRERU1PXEJvb2tTZXJ2aWNlXGFwaVxib29rc1w1?= 
X-Powered-By: ASP.NET 
Date: Sun, 19 Feb 2017 12:09:52 GMT 

Content-Lengthは0ですが、104バイトでなければなりません。

HeadHandlerにブレークポイントを追加してコードをステップ実行すると、レスポンスを返す前にContent-Lengthヘッダーの値を正しく104バイトに設定しているようです。

HeadHandlerの後に実行されているパイプラインには、応答が認識されず、Content-Lengthが0に設定されていますか? HeadHandlerが追加された後に来るWebApiConfig.csの唯一のものは、HttpAttributeルートのマッピングとデフォルトルートの設定ですが、どちらもContent-Lengthヘッダーがリセットされることはないようです。代わりに、どこかの設定が応答に返されるContent-Lengthに影響を与える可能性がありますか?

+0

クライアントに返信するコンテンツヘッダーのHttpResponseMessage用ヘッダーを設定しようとしましたか? – Chizh

+0

@Chizh:あなたが何を意味するか分かりません。私が知る限り、Content-LengthヘッダーはHttpResponseMessage.Content.Headersでのみ定義され、HttpResponseMessage.Headersでは定義されません。 'return response;行にブレークポイントを置くと、コードがSendAsyncメソッドから返ったときにHttpResponseMessage.Content.Headers.ContentLengthが104バイトに設定されていることが確認されました。 –

+0

しかし、 'response.Headers.Add(" Content-Length "、Int32.MaxValue)'を試しましたか?レスポンスが送信されたときには、実際のコンテンツから、 'HttpResponseMessage.Content.Headers.ContentLength'を使って必ず生成されるContent-Lengthヘッダ[*かもしれない*](http://stackoverflow.com/a/32111201/225389) -length = 0 – Chizh

答えて

2

レスポンスのContent.HeadersのContent-Lengthを設定するだけで、レスポンスの新しいコンテンツを作成する必要はありません。 HEADを要求する行為は、とにかく応答から身体内容を取り除く。

public class HeadHandler : DelegatingHandler 
{ 
    private const string Head = "IsHead"; 

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) 
    { 
     if (request.Method == HttpMethod.Head) 
     { 
      request.Method = HttpMethod.Get; 
      request.Properties.Add(Head, true); 
     } 

     var response = await base.SendAsync(request, cancellationToken); 

     object isHead; 
     response.RequestMessage.Properties.TryGetValue(Head, out isHead); 

     if (isHead != null && ((bool)isHead)) 
     { 
      var oldContent = await response.Content.ReadAsByteArrayAsync(); 

      response.Content.Headers.ContentLength = oldContent.Length; 
      return response; 
     } 

     return response; 
    } 
} 
:だから、これはあなたが必要とする必要があるすべてである

...

これは、あなたが引用された記事が書き込まれてからの変化(2013年)行われていないこと、およびもはや最初からコンテンツを作成する必要があります

+0

完璧に働いた、ありがとう。 –

関連する問題