asp.net MVC:IIS何时提供404以及何时将其转发到我的应用程序?

时间:2010-09-20 14:22:17

标签: asp.net-mvc error-handling routing http-status-code-404

我想知道以下事项:

我可以在IIS中定义如何处理page not founds / 404,并且在我的应用中,我可以将其放在我的CustomErrors部分中,或者只是在代码中处理它。

现在我假设IIS总是首先获取请求,它何时为自己处理404,何时让它传递到我的应用程序?

还有一个问题:IIS实际上可以知道asp.net MVC中的请求是否是404,因为它可能或者它可能不是我通过任何route映射的?

5 个答案:

答案 0 :(得分:1)

IIS查看请求扩展。如果注册了一个模块来处理进来的请求类型,那么它会将请求转发给该模块。

例如,如果您从服务器请求foo.jpg,那么IIS内置了一个模块来处理图像/ jpg内容。如果该模块找不到该文件,则返回404。

这里也是一样的。无论你的MVC处理程序不寻找什么(即:图像),IIS都会以另一种方式处理。

答案 1 :(得分:1)

  

IIS实际上可以知道asp.net MVC中的请求是否为404,因为它可能   或者它可能不是我通过任何路线映射的?

我认为这完全取决于控制器工厂如何处理未映射的请求。当DefaultController工厂无法找到路由并让IIS处理错误显示时,它似乎会抛出带有代码404的HttpException。您可以通过创建自己的控制器工厂来玩这个并查看它。

例如,将以下行添加到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,看看当你抛出一个带有代码404的HttpException而不是抛出一个常规异常(或者甚至是一个带有404以外代码的HttpException)时会发生什么。

确保您在IIS(而不是VS Dev Server)下运行项目,因为它们处理这些不同的事情。

答案 2 :(得分:1)

现在我假设IIS总是首先获取请求,它何时处理404本身,以及何时让它传递到我的应用程序?

  

虽然请求最初由ISS处理,但它会传递给MVC应用程序。如果找不到文件,则抛出HttpException,将其冒泡回IIS。如果找到文件,则会直接绕过路由提供服务。

     

但是,您可以通过调整RouteExistingFiles属性来修改行为。如果我没有弄错,虽然当属性设置为true时,您需要创建一个处理所有静态内容的路由(默认为false)。但是,正如一篇文章here建议,根据史蒂夫桑德森,路由系统将首先检查文件是否存在于磁盘上。 (请参阅此related SO question,其中提供了更好的说明,尤其是评论)。

     

亲自尝试一下。使用Application_Error()文件中的Application_EndRequest()Global.asax事件,检查HttpContext.Current.Response对象,了解投放内容时的最终回复。

还有一个问题:IIS能否真正知道asp.net MVC中的请求是否为404,因为它可能或者它可能不是我通过任何路由映射的?

  

这是路线配置发挥作用的地方。由于MVC将检查文件是否首先存在,如果存在,则直接提供服务并绕过路由。关于控制器和操作,同样适用。例如。首先检查/SomeController/ActionThatDoesExist以验证它是否是物理文件。显然,这不是文件,将从应用程序返回404异常。

我认为可能与此问题有关的第三个方面是MVC和IIS如何协同工作。我指的是Integrated ModeClassic Mode。可以找到一个很棒的解释here

答案 3 :(得分:1)

IIS始终处理请求,然后将其转发到MVC应用程序。这是基本决定如何处理它的地方。

如果它们已经是磁盘上的物理文件,则绕过整个路由并提供文件。如果找不到该文件,则尝试匹配路由。如果没有任何作用,那么MVC应用程序可以处理404,否则它会抛出HTTPException并且IIS处理404.

我相信即使在Webforms中,404场景在内部几乎完全相同。唯一的区别是目标始终是物理磁盘,但请求仍然是ASP.NET Webforms,因为您想自己处理404。

答案 4 :(得分:0)

你会想要在你的MVC应用程序中保持执行,就像其他人所说的那样,通常IIS会先将请求传递给MVC,然后只有当MVC将404异常传递到足够高的时候,IIS才能将其恢复并应用它的决定制作过程。

关键是:handle 404's in MVC properly!