当原始请求具有Content时,如何克隆HttpRequestMessage
本文关键字:何克隆 HttpRequestMessage Content 原始 请求 | 更新日期: 2023-09-27 18:15:46
我正在尝试使用这个答案中概述的方法克隆一个请求:https://stackoverflow.com/a/18014515/406322
但是,如果原始请求具有内容,则会得到ObjectDisposedException。
如何可靠地克隆一个HttpRequestMessage?
这应该能奏效:
public static async Task<HttpRequestMessage> CloneHttpRequestMessageAsync(HttpRequestMessage req)
{
HttpRequestMessage clone = new HttpRequestMessage(req.Method, req.RequestUri);
// Copy the request's content (via a MemoryStream) into the cloned object
var ms = new MemoryStream();
if (req.Content != null)
{
await req.Content.CopyToAsync(ms).ConfigureAwait(false);
ms.Position = 0;
clone.Content = new StreamContent(ms);
// Copy the content headers
foreach (var h in req.Content.Headers)
clone.Content.Headers.Add(h.Key, h.Value);
}
clone.Version = req.Version;
foreach (KeyValuePair<string, object?> option in req.Options)
clone.Options.Set(new HttpRequestOptionsKey<object?>(option.Key), option.Value);
foreach (KeyValuePair<string, IEnumerable<string>> header in req.Headers)
clone.Headers.TryAddWithoutValidation(header.Key, header.Value);
return clone;
}
如果你在内容上调用LoadIntoBufferAsync,你可以保证内容在HttpContent对象中被缓冲。剩下的唯一问题是读取流不会重置位置,所以你需要ReadAsStreamAsync并设置流位置= 0。
我的例子与Carlos展示的非常相似…
private async Task<HttpResponseMessage> CloneResponseAsync(HttpResponseMessage response)
{
var newResponse = new HttpResponseMessage(response.StatusCode);
var ms = new MemoryStream();
foreach (var v in response.Headers) newResponse.Headers.TryAddWithoutValidation(v.Key, v.Value);
if (response.Content != null)
{
await response.Content.CopyToAsync(ms).ConfigureAwait(false);
ms.Position = 0;
newResponse.Content = new StreamContent(ms);
foreach (var v in response.Content.Headers) newResponse.Content.Headers.TryAddWithoutValidation(v.Key, v.Value);
}
return newResponse;
}
' ' '
Carlos的答案与一些linq快捷键:
public static async Task<HttpRequestMessage> Clone(this HttpRequestMessage httpRequestMessage)
{
HttpRequestMessage httpRequestMessageClone = new HttpRequestMessage(httpRequestMessage.Method, httpRequestMessage.RequestUri);
if (httpRequestMessage.Content != null)
{
var ms = new MemoryStream();
await httpRequestMessage.Content.CopyToAsync(ms);
ms.Position = 0;
httpRequestMessageClone.Content = new StreamContent(ms);
httpRequestMessage.Content.Headers?.ToList().ForEach(header => httpRequestMessageClone.Content.Headers.Add(header.Key, header.Value));
}
httpRequestMessageClone.Version = httpRequestMessage.Version;
httpRequestMessage.Properties.ToList().ForEach(props => httpRequestMessageClone.Properties.Add(props));
httpRequestMessage.Headers.ToList().ForEach(header => httpRequestMessageClone.Headers.TryAddWithoutValidation(header.Key, header.Value));
return httpRequestMessageClone;
}
.NET版本的更新版本>5 . net
public static async Task<HttpRequestMessage> Clone(this HttpRequestMessage request)
{
var clone = new HttpRequestMessage(request.Method, request.RequestUri)
{
Version = request.Version
};
if (request.Content != null)
{
var ms = new MemoryStream();
await request.Content.CopyToAsync(ms);
ms.Position = 0;
clone.Content = new StreamContent(ms);
request.Content.Headers.ToList().ForEach(header => clone.Content.Headers.TryAddWithoutValidation(header.Key, header.Value));
}
request.Options.ForEach(option => clone.Options.TryAdd(option.Key, option.Value));
request.Headers
.ForEach(header => clone.Headers.TryAddWithoutValidation(header.Key, header.Value));
return clone;
}