Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Re-Send HttpRequestMessage - Exception

I want to send the exact same request more than once, for example:

HttpClient client = new HttpClient(); HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, "http://example.com");  await client.SendAsync(req, HttpCompletionOption.ResponseContentRead); await client.SendAsync(req, HttpCompletionOption.ResponseContentRead); 

Sending the request for a second time will throw an exception with the message:

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

Is their a way to "clone" the request so that I can send again?

My real code has more variables set on the HttpRequestMessage than in the example above, variables like headers and request method.

like image 727
Drahcir Avatar asked Aug 01 '13 17:08

Drahcir


People also ask

Can HttpRequestMessage be reused?

An HttpRequestMessage object can only be used one time; future attempts to use the same object throw an exception.

What is SendAsync?

SendAsync(HttpRequestMessage) Send an HTTP request as an asynchronous operation. SendAsync(HttpRequestMessage, HttpCompletionOption) Send an HTTP request as an asynchronous operation.


2 Answers

I wrote the following extension method to clone the request.

public static HttpRequestMessage Clone(this HttpRequestMessage req) {     HttpRequestMessage clone = new HttpRequestMessage(req.Method, req.RequestUri);      clone.Content = req.Content;     clone.Version = req.Version;      foreach (KeyValuePair<string, object> prop in req.Properties)     {         clone.Properties.Add(prop);     }      foreach (KeyValuePair<string, IEnumerable<string>> header in req.Headers)     {         clone.Headers.TryAddWithoutValidation(header.Key, header.Value);     }      return clone; } 
like image 107
Drahcir Avatar answered Sep 20 '22 13:09

Drahcir


Here is an improvement to the extension method proposed by @drahcir. The improvement is to ensure the content of the request is cloned as well as the request itself:

public static HttpRequestMessage Clone(this HttpRequestMessage request) {     var clone = new HttpRequestMessage(request.Method, request.RequestUri)     {         Content = request.Content.Clone(),         Version = request.Version     };     foreach (KeyValuePair<string, object> prop in request.Properties)     {         clone.Properties.Add(prop);     }     foreach (KeyValuePair<string, IEnumerable<string>> header in request.Headers)     {         clone.Headers.TryAddWithoutValidation(header.Key, header.Value);     }      return clone; }  public static HttpContent Clone(this HttpContent content) {     if (content == null) return null;      var ms = new MemoryStream();     content.CopyToAsync(ms).Wait();     ms.Position = 0;      var clone = new StreamContent(ms);     foreach (KeyValuePair<string, IEnumerable<string>> header in content.Headers)     {         clone.Headers.Add(header.Key, header.Value);     }     return clone; } 

Edit 05/02/18: here's Async version

public static async Task<HttpRequestMessage> CloneAsync(this HttpRequestMessage request) {     var clone = new HttpRequestMessage(request.Method, request.RequestUri)     {         Content = await request.Content.CloneAsync().ConfigureAwait(false),         Version = request.Version     };     foreach (KeyValuePair<string, object> prop in request.Properties)     {         clone.Properties.Add(prop);     }     foreach (KeyValuePair<string, IEnumerable<string>> header in request.Headers)     {         clone.Headers.TryAddWithoutValidation(header.Key, header.Value);     }      return clone; }  public static async Task<HttpContent> CloneAsync(this HttpContent content) {     if (content == null) return null;      var ms = new MemoryStream();     await content.CopyToAsync(ms).ConfigureAwait(false);     ms.Position = 0;      var clone = new StreamContent(ms);     foreach (KeyValuePair<string, IEnumerable<string>> header in content.Headers)     {         clone.Headers.Add(header.Key, header.Value);     }     return clone; } 
like image 41
desautelsj Avatar answered Sep 18 '22 13:09

desautelsj