Domanda

Il mio obiettivo è ritentare un HttpWebRequest asincrono quando fallisce.

Quando Abort () un HttpWebRequest, non posso più BeginGetResponse (). Quindi l'unico modo per richiedere di nuovo probabilmente è ricreare l'oggetto HttpWebRequest. Sembra richiedere molto lavoro poiché dovrei copiare tutte le proprietà dal vecchio oggetto. C'è qualche scorciatoia?

Nota: penso che la serializzazione risolverà il mio problema, ma questa classe non serializzerà, come discusso in domanda precedente .

Aggiorna Rimosso il codice sorgente di esempio perché non era necessario

Vista corrente su questo argomento Non esiste alcun collegamento, l'unico modo per ripetere la richiesta è creare un altro oggetto HttpWebRequest nello stesso modo in cui è stato creato quello originale.

È stato utile?

Soluzione

È possibile!

Devi solo creare un nuovo HttpWebRequest e copiare tutte le proprietà su di esso dal vecchio oggetto tramite reflection.

Ecco un metodo di estensione che consente:

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

Quando si desidera riemettere la stessa richiesta, eseguire semplicemente quanto segue:

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

Altri suggerimenti

Non è possibile.

Un'istanza HTTPWebRequest rappresenta letteralmente un'istanza di richiesta (anche se ci sono casi limite in cui riproverà internamente) e non è quindi qualcosa che può essere logicamente ripetuto. È in grado di restituire esattamente una risposta (richiesta / risposta essendo una coppia logica) e sebbene sia possibile ispezionarla più volte, si otterrà esattamente lo stesso oggetto.

Fondamentalmente, stai pensando che un'istanza HTTPWebRequest sia una sorta di factory, ma è davvero concreta. Devi creare un'altra istanza.

Dove stai cercando di serializzare la richiesta? Potrebbe essere una buona idea serializzare la richiesta prima di provare a farlo, quindi inviare nuovamente la richiesta in caso di errore (dall'istanza serializzata).

Inoltre, potresti voler rimuovere il proxy, serializzare l'istanza e quindi reimpostare il proxy, poiché quello sembra essere il problema nel serializzare la richiesta.

Non esiste alcun collegamento, l'unico modo per ripetere la richiesta è creare un altro oggetto HttpWebRequest nello stesso modo in cui è stato creato quello originale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top