Как снова запросить прерванный запрос HttpWebRequest?

StackOverflow https://stackoverflow.com/questions/411974

  •  03-07-2019
  •  | 
  •  

Вопрос

Моя цель - повторить асинхронный запрос HttpWebRequest в случае сбоя.

Когда я отключаюсь () HttpWebRequest, я не могу BeginGetResponse () снова. Таким образом, единственный способ сделать запрос снова - это воссоздать объект HttpWebRequest. Кажется, это требует большой работы, так как мне придется скопировать все свойства из старого объекта. Есть ли какой-нибудь ярлык?

Примечание. Я думаю, что сериализация решит мою проблему, но этот класс не будет сериализован, как описано в предыдущий вопрос .

Обновление : удален пример исходного кода, поскольку он был ненужным

Текущее представление по этому вопросу Ярлыка не существует, единственный способ повторить запрос - создать другой объект HttpWebRequest так же, как вы создали исходный.

Это было полезно?

Решение

Это возможно!

Вам просто нужно создать новый HttpWebRequest и скопировать в него все свойства из старого объекта с помощью отражения.

Вот метод расширения , который делает это:

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

Если вы хотите повторно выполнить тот же запрос, просто выполните следующее:

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

Другие советы

Это невозможно.

Экземпляр HTTPWebRequest представляет буквально один экземпляр запроса (хотя существуют крайние случаи, когда он будет повторяться внутренне), и поэтому не может быть логически повторен. Он способен возвращать ровно один ответ (запрос / ответ является логической парой), и хотя вы можете проверить этот ответ несколько раз, вы получите точно один и тот же объект.

По сути, вы думаете, что экземпляр HTTPWebRequest - это своего рода фабрика, но она действительно конкретная. Вы должны создать еще один экземпляр.

Где вы пытаетесь сериализовать запрос? Возможно, было бы неплохо сериализовать запрос до того, как вы попытаетесь его выполнить, а затем повторно отправить запрос по ошибке (из сериализованного экземпляра).

Кроме того, вы можете удалить прокси-сервер, сериализовать экземпляр, а затем вернуть его обратно, поскольку, похоже, именно в этом заключается проблема сериализации запроса.

Ярлыка нет, единственный способ повторить запрос - создать другой объект HttpWebRequest так же, как вы создали исходный.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top