Отправка форм на 404 + HttpHandler в IIS7: почему все данные POST пропали?

Хорошо, это может показаться немного запутанным и сложным, так что потерпите меня.

Мы написали структуру, которая позволяет нам определять удобные URL-адреса. Если вы перейдете по любому произвольному URL-адресу, IIS попытается отобразить ошибку 404 (или, в некоторых случаях, 403; 14 или 405). Однако IIS настроен так, что все, что связано с этими конкретными ошибками, отправляется в файл .aspx. Это позволяет нам реализовать HttpHandler для обработки запроса и выполнения работы, что включает поиск связанного шаблона и последующее выполнение всего, что с ним связано.

Теперь все это работает в IIS 5 и 6 и, в некоторой степени, в IIS7, но с одной уловкой, которая случается, когда вы публикуете форму.

Видите ли, когда вы отправляете форму по несуществующему URL-адресу, IIS сообщает «ах, но этот URL-адрес не существует» и выдает ошибку 405 «метод запрещен». Поскольку мы говорим IIS перенаправить эти ошибки на нашу страницу .aspx и, следовательно, обрабатывать их с помощью нашего HttpHandler, это обычно не проблема. Но в IIS7 вся информация POST пропала после перенаправления на 405. И поэтому вы больше не можете выполнять самые тривиальные вещи, связанные с формами.

Чтобы решить эту проблему, мы попытались использовать HttpModule, который сохраняет данные POST, но, похоже, не имеет инициализированного сеанса в нужное время (когда это необходимо). Мы также пытались использовать HttpModule для всех запросов, а не только для отсутствующих запросов, которые достигли 404/403; 14/405, но это означает, что такие вещи, как изображения, css, js и т. д., Обрабатываются кодом .NET, что ужасно неэффективно.

Это подводит меня к собственному вопросу: сталкивался ли кто-нибудь когда-либо с этим, и есть ли у кого-нибудь какие-либо советы или знает ли кто-нибудь, что делать, чтобы все снова заработало? Пока что кто-то предлагал использовать собственный Модуль перезаписи URL от Microsoft. Помогло бы это решить нашу проблему?

Спасибо.

Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
4 867
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Просто предположите: обработчик, указанный в IIS7% windir% \ system32 \ inetsrv \ config \ applicationhost.config, который обрабатывает ваш запрос, вообще не позволяет глаголу POST пройти, и он оценивает это правило, прежде чем определить, не существует.

HttpHandler установлен на verb = "*" (в web.config, а не в applicationHost.config). Я не думаю, что это должно вызвать какие-то проблемы, не так ли?

Rahul 19.09.2008 20:20

Поскольку IIS7 использует .net сверху вниз, использование HttpModule не приведет к снижению производительности. На самом деле существует несколько управляемых модулей HttpModule, которые всегда используются для каждого запроса. Когда запускается событие BeginRequest, возможно, SessionStateModule не был добавлен в коллекцию Modules, поэтому, если вы попытаетесь обработать запрос во время этого события, информация о состоянии сеанса не будет доступна. Установка свойства HttpContext.Handler инициализирует состояние сеанса, если оно требуется запрошенному обработчику, поэтому вы можете просто установить обработчик на свою причудливую страницу 404, которая реализует IRequiresSessionState. Приведенный ниже код должен помочь, хотя вам может потребоваться написать другую реализацию для метода IsMissing ():

using System.Web;
using System.Web.UI;

class Smart404Module : IHttpModule
{
    public void Dispose() {}

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new System.EventHandler(DoMapping);
    }

    void DoMapping(object sender, System.EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;

        if (IsMissing(app.Context))
            app.Context.Handler = PageParser.GetCompiledPageInstance(
                "~/404.aspx", app.Request.MapPath("~/404.aspx"), app.Context);
    }

    bool IsMissing(HttpContext context)
    {
        string path = context.Request.MapPath(context.Request.Url.AbsolutePath);

        if (System.IO.File.Exists(path) || (System.IO.Directory.Exists(path)
            && System.IO.File.Exists(System.IO.Path.Combine(path, "default.aspx"))))
            return true;
        return false;
    }
}

Обновлено: я добавил реализацию IsMissing ()

Примечание. В IIS7 модуль состояния сеанса по умолчанию не запускается глобально. Есть два варианта: включить модуль состояния сеанса для всех запросов (см. Мой комментарий выше относительно запуска управляемых модулей для всех типов запросов) или вы можете использовать отражение для доступа к внутренним членам внутри System.Web.dll.

Спасибо за комментарий! Как только у меня будет возможность попробовать, я дам вам знать, сработало ли это.

Rahul 22.09.2008 12:06

Нет, извините, я нахожусь в середине крайнего срока :( Но я постараюсь обойти его в ближайшие несколько недель.

Rahul 01.10.2008 20:21

Стефан, см. Ответ Мартина ниже

Rahul 14.10.2008 13:16

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

Stefan Rusek 14.10.2008 15:17

Мартин - мой коллега, поэтому он работает с той же проблемой, но спасибо, мы еще раз рассмотрим.

Rahul 14.10.2008 18:44

Да, я определенно рекомендую переписать URL (используя Microsoft IIS7, одну или одну из многих альтернатив). Это специально разработано для предоставления удобных URL-адресов, в то время как документы об ошибках являются последней опорой для сбоев, которые имеют тенденцию искажать входящие данные, поэтому они могут быть не такими, как вы ожидаете.

Ответ принят как подходящий

Microsoft выпустила исправление для этого:

http://support.microsoft.com/default.aspx/kb/956578

Похоже, это работает! Интересно, что Microsoft пришлось исправить, чтобы он заработал;) Спасибо!

Rahul 12.01.2009 13:32

Очевидно, эта загрузка больше не доступна для 32-битных процессоров, только для 64-битных. Странный. Кто-нибудь видел загрузку где-нибудь?

Rahul 26.11.2009 15:38

Проблема в IIS 7, связанная с тем, что пост-переменные не передаются пользовательским обработчикам ошибок, исправлена ​​в пакете обновления 2 для Vista. Не пробовал на Windows Server, но уверен, что и там он будет исправлен.

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