2008-09-19 7 views
2

Хорошо, это может показаться немного запутанным и сложным, так что несите меня.Публикация форм 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 Rewriting module. Помогло бы это решить нашу проблему?

Спасибо.

ответ

0

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

+0

HttpHandler установлен в глагол = "*" (в web.config, а не applicationHost.config). Я не думаю, что это должно вызвать проблемы, не так ли? – Rahul 2008-09-19 16:20:51

2

Поскольку IIS7 использует .net сверху вниз, не было бы накладных расходов на производительность использования HttpModule. На самом деле существует несколько управляемых HttpModules, которые всегда используются для каждого запроса. Когда событие 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; 
    } 
} 

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

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

+0

Спасибо за комментарий! Как только я получу шанс попробовать, я дам вам знать, если это сработает. – Rahul 2008-09-22 08:06:01

+0

Вы уже пробовали? – 2008-09-30 16:49:59

0

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

2

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

 Смежные вопросы

  • Нет связанных вопросов^_^