Response.Redirect не срабатывает из-за кода для предотвращения повторной отправки

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

If Session("orderStatus") <> 'processing' Then

    Session("orderStatus") = 'processing'

    DoThirdPartyStuffThatTakesSomeTime()

    Response.Redirect("confirmationPage.asp", True)

End If

Проблема в том, что если пользователь обновляет страницу, response.redirect не выполняется (даже если остальная часть кода запускается до перенаправления из исходной отправки). Кажется, что новое представление создает новый поток для браузера, который имеет приоритет - он пропускает этот фрагмент кода, очевидно, чтобы предотвратить повторное обращение к сторонним поставщикам, и, поскольку перенаправления нет, просто возвращается на ту же страницу. . Вся вторая отправка может быть завершена до того, как первая отправка завершит свою работу.

Любая помощь в том, как я могу игнорировать все последующие отправки страницы, но все же заставить перенаправление работать ...?

Спасибо


person Marco    schedule 21.04.2010    source источник


Ответы (2)


Переместите вашу редирект из структуры if:

If Session("orderStatus") <> 'processing' Then

  Session("orderStatus") = 'processing'

  DoThirdPartyStuffThatTakesSomeTime()

End If

Response.Redirect("confirmationPage.asp", True)
person Oded    schedule 21.04.2010
comment
Привет, Одед, спасибо за ответ. К сожалению, перенаправление может произойти только после того, как будет выполнено стороннее задание. Если бы я переместил его, вторая отправка ударила бы его первой и перенаправила бы до того, как завершится сторонний материал. - person Marco; 21.04.2010
comment
Затем переместите его в конец функции DoThirdPartyStuffThatTakesSomeTime(). - person Oded; 21.04.2010
comment
Это уже - мой пример кода просто иллюстративный. Это больше связано с двумя потоками, выполняющими одно и то же событие одновременно двумя разными способами (из-за того, что код остановки переменной сеанса выполняется дважды). Кажется, что последний поток имеет приоритет перед тем, куда идет браузер, тогда как мне нужно, чтобы первый поток имел приоритет. - person Marco; 21.04.2010
comment
Я немного рассмотрел это ранее сегодня - но не очень подробно, поскольку я пошел по касательной - хотя я попробую еще раз, так как вы это предложили. Я предполагаю System.Threading.Thread.CurrentThread.Abort () в Try ... Catch. Я дам Вам знать! Спасибо. - person Marco; 21.04.2010
comment
Спасибо за предложение, но после базового тестирования я не уверен, что он сработает. Прерывание потока вызывает исключение ThreadAbortException, с которым не справляется блок Try..Catch (оно генерируется сразу же после попытки try..catch снова, если поток не запускается снова: msdn.microsoft.com/en-us/library/ty8d3wta.aspx). Хммммм, круто это. Спасибо, что подумали об этом! - person Marco; 21.04.2010

После небольшого дополнительного исследования и исследования (включая множество трассировок и отслеживания того, что срабатывает, а также при использовании переменных сеанса) я обнаружил, что ASP.NET автоматически сериализует запросы для данного сеанса, так что каждый из них будет выполняться по очереди. Однако (и это меня смутило), «Ответ», доставленный браузеру, является результатом последнего выполненного действия (при условии, что это действие было инициировано до того, как браузер получил ответ на предыдущее действие). Итак, в моем случае, приведенном выше, весь сторонний код, инициированный первым запросом, завершает выполнение еще до того, как запускается второй запрос. Когда обработка всех запросов завершена, ASP.NET, очевидно, доставляет HTML-код из последнего запроса в IIS (который оказался просто обновлением страницы).

Итак, первое предложение Одеда об отказе от перенаправления было правильным - и я отметил это ответом.

person Marco    schedule 23.04.2010