我想知道以下事项:
我可以在IIS中定义如何处理page not founds / 404
,并且在我的应用中,我可以将其放在我的CustomErrors
部分中,或者只是在代码中处理它。
现在我假设IIS总是首先获取请求,它何时为自己处理404,何时让它传递到我的应用程序?
还有一个问题:IIS实际上可以知道asp.net MVC中的请求是否是404,因为它可能或者它可能不是我通过任何route
映射的?
答案 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 Mode
和Classic 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才能将其恢复并应用它的决定制作过程。