ASP.NET MVC4 не обрабатывает запросы POST в интегрированном режиме IIS7, а в IIS7.5

у меня есть интересный случай, который я не могу объяснить, и мне нужна помощь, чтобы выяснить, в чем моя проблема на IIS7:

дано:

  • ASP.NET веб-приложение MVC 4
  • маршрут по умолчанию зарегистрирован в {controller} / {action}

см. следующий контроллер:

public class ServiceController : Controller
{
    public ActionResult Test()
    {
        return Content("Test");
    }

    [HttpPost]
    public ActionResult Test2()
    {
        return Content("Test2");
    }
}

дополнительно, в глобальном.asax есть такой код:

protected void Application_EndRequest()
{
    if (Context.Response.StatusCode == 404)
    {
        ExecuteIndexPage();
    }
}

protected void Application_Error(object sender, EventArgs e)
{
    var error = Server.GetLastError();
    ExceptionLogger.Log(error);

    ExecuteIndexPage();
}

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

Эта настройка дает очень различное поведение на IIS7 (Windows Server 2008, производственная среда) и IIS7.5 (Win7 Pro, среда разработки и Windows Server 2008 R2, а также производственная среда).

учитывая следующую конфигурацию в IIS (обе версии):

  • Web в IIS настроен с помощью встроенный режим ASP.NET 4 пул приложений
  • устанавливается в системе.раздел вебсервер

на IIS 7.5 поведение:

  • GET request to /: возвращает страницу индекса
  • POST request to /: возвращает страницу индекса
  • получить запрос на / сервис / Тест: возвращает тест
  • POST запрос на / сервис / Тест: возвращает тест
  • вам запрос к /Service/Test2: выполняет глобальный.asax Application_Error: HttpException: открытый метод действия "Test2" не найден на контроллере " MyTestProject.Контроллеры.ServiceController'.
  • POST запрос в /Service / Test2: возвращает Условие_2
  • получить запрос к чему-то есть нет маршрут для: выполняет глобальный.эйсакс End_Request.

на IIS 7 поведение вместо этого:

  • вам запрос к/: возвращает страницу индекса
  • отправить запрос в/: IIS 404 page
  • получить запрос на / сервис / Тест: возвращает тест
  • отправить запрос в / Service / Test: IIS 404 page
  • GET Request to /Service/Test2: выполняет глобальный.asax Application_Error: HttpException: открытый метод действия "Test2" не найден на контроллере " MyTestProject.Контроллеры.ServiceController'.
  • POST запрос в / Service / Test2: возвращает IIS 404 страница
  • получить запрос к чему-то есть нет маршрут для: IIS 404 страница

Итак, IIS 7 и IIS 7.5 отлично работают при использовании запросов GET, за исключением случаев, когда нет маршрута. Когда нет маршрута, IIS 7.5 выполняет глобальный.asax end запрос с кодом состояния 404 и доставляет страницу индекса. IIS 7 делает не выполнить глобальные.запрос конца asax. Почему? Я мог бы (и в настоящее время) обойти эту проблему, зарегистрировав маршрут {*catchall}, чтобы соответствующий маршрут существует.

Как только я пытаюсь использовать HTTP POST, IIS 7 работает даже меньше, чем я ожидал.

при отправке запроса IIS 7 не выполняет никакого кода в моем приложении вообще и напрямую возвращает страницу IIS 404.

Итак, мой вопрос: почему IIS 7 отказывается так трудно обрабатывать запросы POST в моем приложении MVC 4, и что я могу сделать, чтобы он также обрабатывал запрос post?

3 ответов


мы поняли это, - наконец.

конфигурация по умолчанию вставляет это в интернете.config:

<system.webServer>
  <validation validateIntegratedModeConfiguration="false" />
  <modules runAllManagedModulesForAllRequests="true" />
  <handlers>
    <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
    <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>

проблема "*."путь, который охватывал бы / тест.aspx, но не просто / тест.

Если вы измените это на"*", то все запросы будут обрабатываться ExtensionlessUrlHandler, в том числе в статические файлы, которые больше не будут обслуживаться.

поэтому решение: Удалите команду POST из записей обработчика и добавьте новую записи для ExtensionlessUrlHandler с путем, установленным в " * " и только для POST-запросов:

    <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit_post" path="*" verb="POST" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit_post" path="*" verb="POST" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0_post" path="*" verb="POST" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

В идеале удалите те, которые вам не нужны (x86 и x64 в классическом и интегрированном конвейере).


Это может быть связано с некоторыми функциями, которые не установлены (или неправильно) на IIS 7, которые препятствуют правильной работе URL без расширения.

проверьте следующие элементы:

в диалоговом окне "включение или выключение компонентов Windows "панели управления Windows" программы и компоненты " приложение:

  1. перейти к информационным службам Интернета > World Wide Web Services > общие функции HTTP
  2. убедитесь, что " HTTP Выбран параметр" перенаправление ошибок".
  3. убедитесь, что выбран параметр "статическое сжатие содержимого". После выбора нажмите кнопку "OK" для сохранения изменений.

ссылка:http://support.microsoft.com/kb/2023146


возможно, маршрутизация 7 и 7.5 отличается в отношении передачи сообщения действию, у которого нет аргумента, который может принимать данные формы post.

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

возможно, следующим шагом будет попытка добавить аргумент в сообщение, чтобы принять модель, даже если вы не передаете эту модель. Этот модель, очевидно, будет null в результате.