Reputation: 81771
I am wrapping an HttpRequestBase
as an HttpRequestMessage
, which requires all the headers be copied over. But since HttpRequestMessage
is particular about which headers apply to the request object vs. the Content object, the httpRequest.Headers.Add
line below sometimes throws InvalidOperationException.
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;
}
Obviously I'd like my code to not throw exceptions, but rather appropriately apply each header to the appropriate object. How can I predict this? Is there any method I can use to test the applicability of a header short of one that generates and catches exceptions?
Upvotes: 9
Views: 11003
Reputation: 81771
It turns out it's quite simple. This snippet comes heavily inspired from 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);
}
}
}
Upvotes: 15
Reputation: 11
You should be able to use TryAddWithoutValidation instead of Add to avoid the throwing. You need to be careful about whether to call GetBufferlessStream or not depending on whether you want to buffer the request. See ConvertRequest method in the following class: http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/4764b0111b91#src/System.Web.Http.WebHost/HttpControllerHandler.cs
Upvotes: 1