My objective is to retry an asynchronous HttpWebRequest when it fails.
When I Abort() an HttpWebRequest, I cannot BeginGetResponse() again. So the only way to request again probably is recreate the HttpWebRequest object. It seems to require a lot of work since I would have to copy all properties from the old object. Is there any shortcut?
Note: I think that serialization it would solve my problem, but this class won't serialize, as discussed in a previous question.
Update Removed example source code because it was unnecessary
Current view on this matter There is no shortcut, the only way to redo the request is creating another HttpWebRequest object the same way you created the original one.
You just need to create a new HttpWebRequest
and copy all of the properties over to it from the old object via reflection.
Here's an extension method that does this:
/// <summary>
/// Clones a HttpWebRequest for retrying a failed HTTP request.
/// </summary>
/// <param name="original"></param>
/// <returns></returns>
public static HttpWebRequest Clone(this HttpWebRequest original)
{
// Create a new web request object
HttpWebRequest clone = (HttpWebRequest)WebRequest.Create(original.RequestUri.AbsoluteUri);
// Get original fields
PropertyInfo[] properties = original.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
// There are some properties that we can't set manually for the new object, for various reasons
List<string> excludedProperties = new List<String>(){ "ContentLength", "Headers" };
// Traverse properties in HttpWebRequest class
foreach (PropertyInfo property in properties)
{
// Make sure it's not an excluded property
if (!excludedProperties.Contains(property.Name))
{
// Get original field value
object value = property.GetValue(original);
// Copy the value to the new cloned object
if (property.CanWrite)
{
property.SetValue(clone, value);
}
}
}
return clone;
}
When you want to re-issue the same request, simply execute the following:
// Create a request
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://www.google.com/");
// Change some properties...
// Execute it
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Clone the request to reissue it using our extension method
request = request.Clone();
// Execute it again
response = (HttpWebResponse)request.GetResponse();