我正在使用RC2
使用URL路由:
routes.MapRoute(
"Error",
"{*url}",
new { controller = "Errors", action = "NotFound" } // 404s
);
Run Code Online (Sandbox Code Playgroud)
以上似乎照顾这样的请求(假设默认路由表由初始MVC项目设置):"/ blah/blah/blah/blah"
覆盖控制器本身中的HandleUnknownAction():
// 404s - handle here (bad action requested
protected override void HandleUnknownAction(string actionName) {
ViewData["actionName"] = actionName;
View("NotFound").ExecuteResult(this.ControllerContext);
}
Run Code Online (Sandbox Code Playgroud)
但是,之前的策略不处理对Bad/Unknown控制器的请求.例如,我没有"/ IDoNotExist",如果我请求这个,我从Web服务器获取通用404页面而不是我的404,如果我使用路由+覆盖.
最后,我的问题是: 有没有办法在MVC框架中使用路由或其他东西来捕获这种类型的请求?
或者我应该默认使用Web.Config customErrors作为我的404处理程序并忘记所有这些?我假设如果我使用customErrors,由于Web.Config对直接访问的限制,我必须在/ Views之外存储通用404页面.
如果给出路线:
{FeedName}/{ItemPermalink}
例如:/ Blog/Hello-World
如果该项不存在,我想返回404.在ASP.NET MVC中执行此操作的正确方法是什么?
在旧网站中,我通过添加redirectMode="ResponseRewrite"(3.5 SP1中的新增功能)来更改CustomErrors的工作方式:
<customErrors mode="RemoteOnly" defaultRedirect="Error.aspx" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="404.aspx" />
</customErrors>
Run Code Online (Sandbox Code Playgroud)
问题是:它向我显示了一般错误页面(当你没有设置时你得到的那个customErrors.如果我删除redirectMode="ResponseRewrite"部分,它工作正常.
我确定服务器中安装了3.5 SP1,因为我在同一服务器上托管的其他站点上使用相同的设置.
有任何想法吗?
我们可能知道,例如customErrors和httpErrors有什么区别?,CustomErrors是一种在Web应用程序中定义错误页面的旧方法,但这种方法存在一些问题 - 例如,如果您关心正确的http响应代码,因为CustomErrors的方法是重定向到错误页面而不是替换当前响应,它通过http状态代码破坏了通信的大部分语义完整性.
自IIS 7.0以来,HttpErrors是一个更新的功能,它在服务器级而不是应用程序级运行,并且更适合以有效的方式处理错误响应,例如通过使用当前响应而不是重定向.
但是,如果在我看来,ASP.NET中这些工件的基础结构如今看起来给我们带来了一些问题.
一个简单的配置作为例子
<httpErrors existingResponse="Auto" errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="/Error/E404" responseMode="ExecuteURL" />
</httpErrors>
Run Code Online (Sandbox Code Playgroud)
我们将errorMode设置为Custom,因为我们要测试错误处理本身,并将existingResponse设置为Auto,这将引入依赖于Response.TrySkipIisCustomErrors的分支:
理想情况下,这将允许我们自己处理一些错误,例如当../product/id中的产品不存在时,我们可以手动返回特定的404页面,其中包含有关缺失产品的信息,并且仍然让HttpErrors模块处理所有错误像..产品 /名称,但是只是../misspelledandunmatchableurl.
但是,据我所知,这是行不通的.原因在于内部方法System.Web.HttpResponse .ReportRuntimeError,它将在运行时错误(例如未找到控制器/操作)上调用,并且我们有一个如下所示的部分:
// always try to disable IIS custom errors when we send an error
if (_wr != null) {
_wr.TrySkipIisCustomErrors = true;
}
if (!localExecute) {
code = HttpException.GetHttpCodeForException(e);
// …Run Code Online (Sandbox Code Playgroud) 我已经为ASP.NET MVC 3中的一般情况实现了404处理,因为没有找到控制器/视图.但是,如果用户试图访问无法找到的内容,应如何在控制器内部进行处理?例如www.foo.bar/Games/Details/randomjunk将在里面调用GamesController:
public ActionResult Details(string id) // id is 'randomjunk'
{
if(DoesGameExist(id) == false)
// Now what?
Run Code Online (Sandbox Code Playgroud)
我可以做一个,return Redirect('/Errors/Http404');但这似乎不是正确的方法.你应该抛出异常还是别的什么?
在这种情况下我们可以有一个特殊的观点,但首先我们需要一个很好的方法来应用于几个案例.
编辑:我想展示我已经拥有的友好404页面的一般情况.