Question

Mon objectif est de réessayer un HttpWebRequest asynchrone en cas d'échec.

Quand je Abandonner () un HttpWebRequest, je ne peux pas encore BeginGetResponse (). La seule façon de demander à nouveau est probablement de recréer l'objet HttpWebRequest. Cela semble nécessiter beaucoup de travail car je devrais copier toutes les propriétés de l'ancien objet. Y a-t-il un raccourci?

Remarque: je pense que la sérialisation résoudrait mon problème, mais cette classe ne sera pas sérialisée, comme indiqué dans une question précédente .

Mettre à jour Exemple de code source supprimé, car il était inutile

Vue actuelle sur ce sujet Il n'y a pas de raccourci, le seul moyen de rétablir la demande consiste à créer un autre objet HttpWebRequest de la même manière que vous avez créé l'original.

Était-ce utile?

La solution

C'est possible!

Il vous suffit de créer un nouveau HttpWebRequest et de lui copier toutes les propriétés depuis l'ancien objet via réflexion.

Voici une méthode d'extension qui effectue ceci:

/// <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;
}

Lorsque vous souhaitez réémettre la même demande, exécutez simplement les opérations suivantes:

// 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();

Autres conseils

Ce n'est pas possible.

Une instance HTTPWebRequest représente littéralement une instance de requête (bien qu'il existe des cas extrêmes où elle réessayera en interne) et n'est donc pas quelque chose qui peut être répété logiquement. Il est capable de renvoyer exactement une réponse (demande / réponse étant une paire logique). Bien que vous puissiez inspecter cette réponse plusieurs fois, vous obtiendrez exactement le même objet.

En gros, vous pensez qu'une instance de HTTPWebRequest est une sorte d’usine, mais c’est vraiment concret. Vous devez créer une autre instance.

Où essayez-vous de sérialiser la demande? Il peut être judicieux de sérialiser la requête avant de la créer, puis de la renvoyer en cas d'échec (à partir de l'instance sérialisée).

Vous pouvez également souhaiter supprimer le proxy, sérialiser l'instance, puis le réinitialiser, car il semble que le problème réside dans la sérialisation de la demande.

Il n'y a pas de raccourci, le seul moyen de rétablir la demande consiste à créer un autre objet HttpWebRequest de la même manière que vous avez créé l'objet d'origine.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top