Wie wieder eine abgebrochene HttpWebRequest beantragen?
-
03-07-2019 - |
Frage
Mein Ziel ist es, ein asynchrones erneut zu versuchen HttpWebRequest, wenn es fehlschlägt.
Wenn ich Abort () ein HttpWebRequest, ich kann nicht BeginGetResponse () erneut. So ist die einzige Art und Weise wieder wahrscheinlich zu verlangen, ist das HttpWebRequest Objekt neu erstellen. Es scheint eine Menge Arbeit zu verlangen, da ich alle Eigenschaften aus dem alten Objekt kopieren müsste. Gibt es eine Abkürzung?
Hinweis: Ich denke, dass die Serialisierung wäre es mein Problem zu lösen, aber diese Klasse nicht serialisiert werden, wie in einem vorige Frage .
Aktualisieren Entfernte Beispiel-Quellcode, weil es nicht notwendig war
Aktuelle Ansicht zu diesem Thema Es gibt keine Abkürzung, der einzige Weg, um die Anforderung zu wiederholen ist ein anderer HttpWebRequest Objekt die gleiche Art und Weise zu schaffen Sie das Original erstellt.
Lösung
Es ist möglich!
Sie müssen nur einen neuen HttpWebRequest
erstellen und alle Eigenschaften über es aus dem alten Objekt über Reflexion kopieren.
Hier ist eine Erweiterungsmethode , das tut dies:
/// <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;
}
Wenn Sie die gleiche Aufforderung an re-issue, füllen Sie einfach führen Sie das folgende:
// 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();
Andere Tipps
Es ist nicht möglich.
Eine HttpWebRequest-Instanz stellt buchstäblich eine Anforderungsinstanz (obwohl es Grenzfälle, wo es intern wiederholen wird), und ist daher nicht etwas, was logisch wiederholt werden kann. Es ist in der Lage Rückkehr genau eine Antwort (Request / Response ein logisches Paar ist), und obwohl Sie, dass die Antwort mehrmals überprüfen können Sie bekommen genau das gleiche Objekt.
Im Grunde sind Sie denken, eine HttpWebRequest-Instanz ist eine Art Fabrik, aber es ist wirklich konkret. Sie müssen eine andere Instanz erstellen.
Wo wollen Sie die Anfrage zur Serialisierung? Es könnte eine gute Idee sein, die Anforderung serialisiert vor Sie versuchen, es zu machen, und dann die Anforderung bei einem Fehler erneut (von der serialisierten Instanz).
Auch mögen Sie vielleicht den Proxy entfernen, um die Instanz serialisiert und dann den Proxy wieder eingestellt, denn das scheint zu sein, wo das Problem liegt die Anforderung in der Serialisierung.
Es gibt keine Abkürzung, der einzige Weg, um die Anforderung zu wiederholen schafft eine andere HttpWebRequest die gleiche Art und Weise Objekt, um das Original erstellt.