在运行在IIS 6上的ASP.NET MVC 3应用程序中处理404错误

4

标题已经说明了一切。实际上有很多关于如何做到这一点的信息,我非常接近成功。我在Google上读了几篇文章,以及以下stackoverflow帖子:

如何在ASP.NET MVC中正确处理404错误?

如何在ASP.NET MVC中正确处理404错误?

ASP.NET MVC3上的自定义错误页面

http://blog.davebouwman.com/2011/04/21/custom-404-pages-for-asp-net-mvc-3/

我已经在操作级别上使404错误正常工作。我在我的控制器上使用*.aspx后缀。如果您拥有像这样的URL

"http://blahblah/AppName/idontexist.aspx"

自定义错误控制器已加载。我的问题在于没有 .aspx 且不存在的控制器。这会产生典型的 IIS 服务器 404 html 页面,而我不想要这样。另一个问题是我不能真正改变 IIS 配置本身。我必须通过代码/web.config/global.asax(或项目中我还没有想到的其他部分)来处理这个问题。
以下是我的 web.config 条目(这是根 web.config,而不是视图文件的 web.config):
<httpErrors defaultPath="/Error.aspx/HttpError" errorMode="Custom" existingResponse="Replace" defaultResponseMode="ExecuteURL">
  <remove statusCode="500" subStatusCode="-1" />
  <remove statusCode="404" subStatusCode="-1" />
  <error statusCode="500" path="/Error.aspx/HttpError" responseMode="ExecuteURL" />
  <error statusCode="404" path="/Error.aspx/NotFound" responseMode="ExecuteURL" />
</httpErrors>

<customErrors mode="On"  defaultRedirect="~/Error.aspx/HttpError">
  <error redirect="~/Error.aspx/NotFound" statusCode="404" />
</customErrors>  

这是我的global.asax中的路由:

       routes.MapRoute(
            "Default", // Route name
            "{controller}.aspx/{action}/{id}", // URL with parameters
            new { controller = "StartController", action = "StartAction", id = UrlParameter.Optional } // Parameter defaults
        );

        routes.MapRoute(
            "NotFoundController", // Route name
            "{controller}.aspx", // URL with parameters
            new { controller = "Error", action = "NotFound" } // Parameter defaults
        );

        routes.MapRoute(
            "NotFoundController2", // Route name
            "{controller}", // URL with parameters
            new { controller = "Error", action = "NotFound" } // Parameter defaults
        );

        routes.MapRoute(
            "Root", // Route name
            "", // URL with parameters
            new { controller = "StartController", action = "StartAction", id = UrlParameter.Optional } // Parameter defaults
        );

我认为使用路由来捕获这些问题的一个障碍是我失去了404状态码;然而,由于该路由指向专门设计用于此目的的操作,所以我想那一点无关紧要。无论如何,欢迎任何想法、建议或批评。我在这里非常接近。谢谢!
编辑1: 我仍在研究这个问题。是否有一种方法可以定义自定义路由约束,如果在url中找不到“.aspx”文本,则重定向到错误控制器?
编辑2:看起来约束并不是用来这样使用的。我也尝试实现
    protected void Application_Error()
    {
    }

按照http://blog.davebouwman.com/2011/04/21/custom-404-pages-for-asp-net-mvc-3/的实现方式,但当我不为控制器指定.aspx时,似乎应用程序永远没有机会抛出错误。看起来这是在我的应用程序能够响应之前由IIS处理的。
如果我可以进行IIS更改,最好是只针对此应用程序的虚拟目录条目,那么是否可以提供更可行的解决方案?
如果有一个地方可以获取URL,搜索.aspx,如果未找到则引发404未找到,但重定向到应用程序级别的404页面而不是IIS默认页面,那将非常接近理想状态。
你有什么想法? 编辑3 我认为,除非您的应用程序是IIS服务器的根站点而不是虚拟目录,否则处理这种情况是不可能的。我注意到,在IIS 6.0中,您可以调整默认的IIS错误页面。不仅如此,您还可以将某些情况替换为URL。我尝试在虚拟目录站点上执行此操作,但显示了默认的IIS 404未找到页面。
因此,如果您对设置和站点具有巨大的控制力,并且正在为其进行此操作的站点是根站点,则可以在IIS 6上处理此问题。
我想在实际场景中并不适用。

2
404错误处理可以是多么麻烦,真是令人难以置信。 - James Lawruk
这里有更多的帮助... http://www.devcurry.com/2012/06/aspnet-mvc-handling-exceptions-and-404.html - Amitd
这真的很惊人。我怀疑该应用程序的用户会去调整URL,但使用默认的IIS页面看起来不够专业。 - jason
感谢@Amitd提供的链接。它涵盖了在IIS 7上处理的内容。实际上,我现在已经做了几乎所有这些事情。我认为问题是IIS 6特定的,因为我的控制器必须以.aspx结尾,以便IIS 6能够正确地将流量路由到ASP.NET MVC 3。 - jason
1个回答

1
我认为如果不能更改IIS,这是不可能的。在IIS 6中,除非将请求映射到ASP.Net ISAPI处理程序(aspnet_isapi.dll),否则请求不会进入ASP.Net领域。对于普通的ASP.Net扩展名,在安装.Net时已经在IIS6中设置了映射(.ashx、.aspx等)。这就是为什么不存在的控制器会得到正常的IIS 404页面的原因。IIS正在寻找磁盘上不存在的文件夹。
为了使您的404页面处理程序按预期工作(假设您可以更改IIS),您需要设置所谓的通配符映射。这将发送所有请求到ASP.Net ISAPI。IIS还需要被指示绕过对物理文件的检查,因为在这种情况下不存在任何文件。有一个复选框用于该选项。我不再面前有IIS 6,但这个网站的选项1会引导您完成它:

http://blog.stevensanderson.com/2008/07/04/options-for-deploying-aspnet-mvc-to-iis-6/

我以前做过这个,它确实可行。将所有内容发送到 .Net ISAPI 会有一些权衡。所有静态文件(包括图片)都将由 ASP.Net 处理,而不是直接由 IIS 处理,因此请注意其影响。
希望这能帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接