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

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

  •  01-07-2019
  •  | 
  •  

Вопрос

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

Мы написали структуру, которая позволяет нам определять удобные 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, что ужасно неэффективно.

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

Спасибо.

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

Решение

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

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

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

Поскольку IIS7 использует .net сверху вниз, использование HttpModule не приведет к увеличению производительности. На самом деле существует несколько управляемых HttpModule, которые всегда используются при каждом запросе.При запуске события BeginRequest SessionStateModule, возможно, не был добавлен в коллекцию модулей, поэтому, если вы попытаетесь обработать запрос во время этого события, информация о состоянии сеанса не будет доступна.Установка свойства 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.

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

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

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

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