Pergunta

Meu objetivo é repetir uma assíncrona HttpWebRequest quando ele falhar.

Quando eu Abort () um HttpWebRequest, não posso BeginGetResponse () novamente. Assim, a única forma de solicitar novamente provavelmente é recriar o objeto HttpWebRequest. Ele parece exigir muito trabalho desde que eu teria que copiar todas as propriedades do objeto de idade. Existe algum atalho?

Nota: Eu acho que a serialização que iria resolver o meu problema, mas essa classe não vai serialize, como discutido em uma pergunta anterior .

Atualizar exemplo Removido o código fonte porque era desnecessário

Vista actual sobre este assunto Não há nenhum atalho, a única maneira de refazer a solicitação é criar outra HttpWebRequest objeto da mesma forma que criou o original.

Foi útil?

Solução

É possível!

Você só precisa criar uma nova HttpWebRequest e copiar todas as propriedades até lá a partir do objeto de idade através da reflexão.

Aqui está um método de extensão que faz isso:

/// <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 você quiser re-emitir o mesmo pedido, simplesmente executar a seguinte:

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

Outras dicas

Não é possível.

instância Uma httpwebrequest representa literalmente uma instância pedido (embora existam casos extremos, onde ele tentará novamente internamente), e, portanto, não é algo que pode, logicamente, ser repetido. Ele é capaz de retornar exatamente uma resposta (request / response sendo um par lógico), e embora você pode inspecionar que vários resposta vezes você vai ter exatamente o mesmo objeto.

Basicamente, você está pensando uma instância httpwebrequest é uma espécie de fábrica, mas é realmente concreto. Você tem que criar outra instância.

Onde você está tentando serializar o pedido? Pode ser uma boa idéia para serializar o pedido antes você tentar fazê-lo, e depois reenviar o pedido em caso de falha (a partir da instância serializada).

Além disso, você pode querer remover o proxy, serializar o exemplo, e em seguida, defina a parte de trás proxy, uma vez que parece ser o lugar onde as mentiras de problema na serialização o pedido.

Não há nenhum atalho, a única maneira de refazer a solicitação é criar outra HttpWebRequest objeto da mesma forma que criou o original.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top