2013-03-04 12 views
8

HttpRequestMessageとしてHttpRequestBaseをラップしています。すべてのヘッダーをコピーする必要があります。しかし、HttpRequestMessageは、リクエストオブジェクトとContentオブジェクトのどちらにヘッダーが適用されるかに関する特定なので、以下の行のhttpRequest.Headers.AddがInvalidOperationExceptionをスローすることがあります。ヘッダー名を考慮してHttpRequestBaseをHttpRequestMessageに変換する方法

public static HttpRequestMessage AsHttpRequestMessage(this HttpRequestBase request) { 
    Requires.NotNull(request, "request"); 

    var httpRequest = new HttpRequestMessage(new HttpMethod(request.HttpMethod), request.Url); 
    foreach (string header in request.Headers) { 
     httpRequest.Headers.Add(header, request.Headers.GetValues(header)); 
    } 

    if (request.Form != null) { 
     // Avoid a request message that will try to read the request stream twice for already parsed data. 
     httpRequest.Content = new FormUrlEncodedContent(request.Form.AsKeyValuePairs()); 
    } else if (request.InputStream != null) { 
     httpRequest.Content = new StreamContent(request.InputStream); 
    } 

    return httpRequest; 
} 

はもちろん、私は例外をスローではなく、適宜、オブジェクトに各ヘッダを適用しないように私のコードをしたいと思います。どうすればこのことを予測できますか?例外を生成してキャッチするヘッダーの適用範囲をテストするために使用できるメソッドはありますか?

+0

私は実際にはヘッダーの配置よりも難しいと感じています。いくつかのヘッダ(Content-Typeのような)は 'Add 'されることはありませんが、ContentTypeプロパティを使ってのみ設定できます。 'Accept'は別のヘッダーで、明らかに私はより豊かなオブジェクトを使って解析して渡す必要があります。確かにこの作品はすでに完成しており、ここでやり直す必要はありませんか? –

+0

あなたのコードでは、あなたがrequest.Formまたはrequest.Contentを読んでいるのを見ました。 HttpRequestBaseオブジェクトが両方とも重要なコンテンツを持つことができるかどうかを知りたいのです。 – StackOverflowVeryHelpful

+0

@StackOverflowVeryHelpful:いいえ。フォームデータがコンテンツに含まれています。したがって、Formがnullでない場合は、要求入力ストリームがフォームデータを持ち、ASP.NETが解析したことを示すHTTPヘッダーが要求に含まれていることを意味します。この場合、InputStreamには何も残っていません。 –

答えて

13

非常に簡単です。このスニペットは大きくASP.NET's own open sourced source codeからインスピレーションを受けています。

/// <summary> 
/// Clones an <see cref="HttpWebRequest" /> in order to send it again. 
/// </summary> 
/// <param name="message">The message to set headers on.</param> 
/// <param name="request">The request with headers to clone.</param> 
internal static void CopyHeadersFrom(this HttpRequestMessage message, HttpRequestBase request) { 
    Requires.NotNull(request, "request"); 
    Requires.NotNull(message, "message"); 

    foreach (string headerName in request.Headers) { 
     string[] headerValues = request.Headers.GetValues(headerName); 
     if (!message.Headers.TryAddWithoutValidation(headerName, headerValues)) { 
      message.Content.Headers.TryAddWithoutValidation(headerName, headerValues); 
     } 
    } 
} 
関連する問題