asp.net MVC: когда IIS дает 404 и когда он передает его в мое приложение? - PullRequest
3 голосов
/ 20 сентября 2010

мне было интересно узнать следующее:

я могу определить в IIS, что делать с page not founds / 404, а также в своем приложении я могу поместить его в мой CustomErrors раздел или просто обработать его в коде.

Теперь, когда я предполагаю, что IIS всегда получает запрос первым, когда он обрабатывает 404 для себя и когда он пропускает его в мое приложение?

И дополнительный вопрос: может ли IIS действительно знать, является ли запрос в asp.net MVC 404, потому что он может или не может быть отображен через любой route?

Ответы [ 5 ]

1 голос
/ 11 октября 2010

IIS всегда обрабатывает запрос и затем перенаправляет его в приложение MVC. Вот где в основном решено, как с этим справиться.

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

Я верю, что даже в веб-формах сценарий 404 практически одинаков внутри. Единственной разницей в том, что целью является всегда физический диск, но запрос по-прежнему направляется в веб-формы ASP.NET, если вы хотите обработать 404 самостоятельно.

1 голос
/ 06 октября 2010

может ли IIS действительно знать, является ли запрос в asp.net MVC 404, потому что он может или не может быть отображен через любой маршрут?

Я думаю, все зависит от того, какфабрика вашего контроллера обрабатывает неотвеченный запрос.Кажется, фабрика DefaultController генерирует исключение HttpException с кодом 404, когда не может найти маршрут и позволяет IIS обрабатывать отображение ошибок.Вы можете поиграть с этим и увидеть его в действии, создав собственную фабрику контроллеров.

Например, добавьте следующую строку в ваш Application_Start

ControllerBuilder.Current.SetControllerFactory(new TestControllerFactory());

и добавьте этот класс в совершенно новыйПроект MVC:

public class TestControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            //throw new Exception("Oops!");                               // yellow screen of death
            throw new System.Web.HttpException(404, "Oops not found!"); // bubbles up to IIS
        }
        return base.GetControllerInstance(requestContext, controllerType);
    }
}

Перейдите к своему проекту на http://localhost/MvcApplication1/unmapped и посмотрите, что происходит, когда вы генерируете HttpException с кодом 404 по сравнению с тем, когда вы бросаете обычное исключение (или даже HttpException с кодомкроме 404)

Убедитесь, что ваш проект работает под управлением IIS (а не VS Dev Server), поскольку они обрабатывают эти вещи по-разному.

1 голос
/ 07 октября 2010

Теперь, когда я предполагаю, что IIS всегда сначала получает запрос, когда он обрабатывает 404 для себя и когда он пропускает его в мое приложение?

Хотя запрос первоначально обрабатывался ISS, он был передан приложению MVC.Если файл не найден, создается исключение HttpException, которое возвращается в IIS.Если файл найден, он обслуживается напрямую в обход маршрутизации.

Однако вы можете изменить поведение, настроив свойство RouteExistingFiles .Если я не ошибаюсь, вам нужно будет создать маршрут для обработки всего статического содержимого, когда для свойства установлено значение true (по умолчанию false).Однако, как пишет здесь , согласно Стиву Сандерсону, система маршрутизации сначала проверит, существует ли файл на диске.(См. Этот связанный вопрос SO , который обеспечивает лучшее разъяснение, особенно комментарии).

Попробуйте сами.Используйте события Application_Error() и Application_EndRequest() в файле Global.asax и осмотрите объект HttpContext.Current.Response, чтобы увидеть, какие будут окончательные ответы при доставке контента.

И дополнительный вопрос: может ли IIS действительно знать, является ли запрос в asp.net MVC 404, потому что он может или не может быть сопоставлен мне по какому-либо маршруту?

Здесь конфигурация маршрута вступает в игру.Так как MVC проверит, существует ли файл первым, если он существует, он обслуживается напрямую, и маршрутизация обходится.Что касается контроллеров и действий, то же самое будет применяться.Например./SomeController/ActionThatDoesExist сначала проверяется, чтобы убедиться, что это физический файл.Ясно, что это не файл, и из приложения будет возвращено исключение 404.

Третий аспект, который, я думаю, может быть связан с этим вопросом, заключается в том, как MVC и IIS работают вместе.Я имею в виду Integrated Mode и Classic Mode.Потрясающее объяснение можно найти здесь .

1 голос
/ 06 октября 2010

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

Например, если вы запрашиваете foo.jpg со своего сервера, в IIS встроен модуль для обработки изображений / jpg. Если этот модуль не может найти файл, он возвращает 404.

То же самое и здесь. Что бы ваши обработчики MVC не искали (например, изображения), IIS позаботится об этом по-другому.

0 голосов
/ 07 октября 2010

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

Ключ: Правильно обрабатывать 404 в MVC!

...