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

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

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

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

Обновлять Удален пример исходного кода, потому что он не нужен

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
0
4 011
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

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

Jader Dias 05.01.2009 14:21

удалил образец кода сериализации и заменил его ссылкой на другой вопрос SO о сериализации HttpWebRequest (stackoverflow.com/questions/351265/…)

Jader Dias 05.01.2009 16:14

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

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

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

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

Есть способ, посмотрите мой ответ.

Elad Nava 18.01.2016 20:48
Ответ принят как подходящий

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

Вам просто нужно создать новый 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();

Блестяще. Спасибо.

Sean 25.10.2017 22:02

Отличная идея! Но я не уверен, какие заголовки вы бы хотели скопировать нет. Например, если у вас есть информация для авторизации, вам нужно будет скопировать заголовки (по крайней мере, некоторые из них) для следующей успешной попытки.

Gyromite 15.09.2020 18:33

Метод расширения не копирует заголовки, поскольку C# выдает исключение при попытке записать полные заголовки в это свойство. Вам нужно будет настроить код, чтобы читать каждый отдельный заголовок как пару «ключ-значение» и записывать его в новый клонированный объект, по одному заголовку за раз.

Elad Nava 16.09.2020 00:19

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