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" программы и компоненты " приложение:
- перейти к информационным службам Интернета > World Wide Web Services > общие функции HTTP
- убедитесь, что " HTTP Выбран параметр" перенаправление ошибок".
- убедитесь, что выбран параметр "статическое сжатие содержимого". После выбора нажмите кнопку "OK" для сохранения изменений.
возможно, маршрутизация 7 и 7.5 отличается в отношении передачи сообщения действию, у которого нет аргумента, который может принимать данные формы post.
Если ваш код никогда не попадает, это будет означать, что маршрутизация не нашла соответствия для подписи, аргументов и встроенных ограничений, которые она проверяет перед передачей в код.
возможно, следующим шагом будет попытка добавить аргумент в сообщение, чтобы принять модель, даже если вы не передаете эту модель. Этот модель, очевидно, будет null в результате.