ASP.NET MVC - 如何抛出类似于 StackOverflow 上的 404 页面
我目前有一个继承自 System.Web.Mvc.Controller 的 BaseController 类。在该类上,我有 HandleError
属性,它将用户重定向到“500 - 哎呀,我们搞砸了”页面。目前这正在按预期进行。
这有效
<HandleError()> _
Public Class BaseController : Inherits System.Web.Mvc.Controller
''# do stuff
End Class
我的 404 页面也以 Per-ActionResult 为基础工作,它再次按预期工作。
这很有效
Function Details(ByVal id As Integer) As ActionResult
Dim user As Domain.User = UserService.GetUserByID(id)
If Not user Is Nothing Then
Dim userviewmodel As Domain.UserViewModel = New Domain.UserViewModel(user)
Return View(userviewmodel)
Else
''# Because of RESTful URL's, some people will want to "hunt around"
''# for other users by entering numbers into the address. We need to
''# gracefully redirect them to a not found page if the user doesn't
''# exist.
Response.StatusCode = CInt(HttpStatusCode.NotFound)
Return View("NotFound")
End If
End Function
再说一遍,这非常有效。如果用户输入类似 http://example.com/user/999 的内容(其中 userID 999 不不存在),他们将看到相应的 404 页面,但 URL 不会更改(他们不会重定向到错误页面)。
我无法实现这个想法
这就是我遇到的问题。如果用户输入 http://example.com/asdf- 他们会被踢到通用 404 页面。我想要做的是保持 URL 不变(IE:不重定向到任何其他页面),而只是显示“NotFound”视图并将 HttpStatusCode.NotFound
推送到客户端。
例如,只需访问 https://stackoverflow.com/asdf,您将在其中看到自定义 404 页面并看到留在机智。
显然我错过了一些东西,但我无法弄清楚。由于“asdf”实际上并不指向任何控制器,因此我的基本控制器类没有启动,因此我无法在其中的“HandleError”过滤器中执行此操作。
预先感谢您的帮助。
注意:我绝对不想将用户重定向到 404 页面。我希望它们保留在现有的 URL,并且我希望 MVC 将 404 VIEW 推送给用户。
编辑:
我也尝试过以下方法,但无济于事。
Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
routes.RouteExistingFiles = False
routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
routes.IgnoreRoute("Assets/{*pathInfo}")
routes.IgnoreRoute("{*robotstxt}", New With {.robotstxt = "(.*/)?robots.txt(/.*)?"})
routes.AddCombresRoute("Combres")
''# MapRoute allows for a dynamic UserDetails ID
routes.MapRouteLowercase("UserProfile", _
"Users/{id}/{slug}", _
New With {.controller = "Users", .action = "Details", .slug = UrlParameter.Optional}, _
New With {.id = "\d+"} _
)
''# Default Catch All Valid Routes
routes.MapRouteLowercase( _
"Default", _
"{controller}/{action}/{id}/{slug}", _
New With {.controller = "Events", .action = "Index", .id = UrlParameter.Optional, .slug = UrlParameter.Optional} _
)
''# Catch All InValid (NotFound) Routes
routes.MapRoute( _
"NotFound", _
"{*url}", _
New With {.controller = "Error", .action = "NotFound"})
End Sub
我的“NotFound”路线什么也没做。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在我的另一个上找到了我的答案所以问题。非常感谢 Anh-Kiet Ngo 提供的解决方案。
Found my answer on my other SO question. Thanks very much Anh-Kiet Ngo for the solution.
您可以尝试:
http://msdn。 microsoft.com/en-us/library/system.web.configuration.customerrorssection.redirectmode.aspx
You could try :
http://msdn.microsoft.com/en-us/library/system.web.configuration.customerrorssection.redirectmode.aspx
路由是模式匹配。您未找到的路由不起作用,因为错误 URL 的模式与较早的路由匹配。
因此:
如果您输入: http://example.com/asdf- 则与“默认”匹配上面的路线 - MVC 寻找
asdf-Controller
但找不到它,因此抛出异常。如果您访问 http://example.com/asdf-/action/id/ slug/extra 那么“Default”不再匹配,并且将遵循“NotFound”路线。
您可以将所有已知控制器的过滤器添加到“默认”路由,但是当您添加新控制器时,维护起来会很痛苦。
您根本不需要挂钩
Application_Error
事件,但我还没有找到解决丢失控制器的更好方法 - 我将其询问为 另一个问题。Routes are pattern matches. Your not found route isn't working because the pattern of your incorrect URL matches an earlier route.
So:
If you enter: http://example.com/asdf- then that matches the "Default" route above - MVC goes looking for
asdf-Controller
and can't find it, so exception thrown.If you go to http://example.com/asdf-/action/id/slug/extra then "Default" no longer matches and the "NotFound" route will be followed instead.
You could add a filter for all your known controllers to the "Default" route, but that's going to be a pain to maintain when you add new controllers.
You shouldn't need to hook into the
Application_Error
event at all, but I haven't found a better way around the missing controller yet - I asked it as another question.我通过简单地返回基本控制器中定义的操作来实现此功能,而不是重定向到它。
(“SearchUtilities.GetPageNotFoundModel”位是关于通过将 URL 输入到我们的搜索引擎中来生成建议)
在继承基础的任何操作方法中,我可以简单地调用此方法:
... 每当我捕获无效参数时。包罗万象的路线也有同样的作用。
I got this to work by simply returning the action defined in the base controller, rather than redirecting to it.
(The "SearchUtilities.GetPageNotFoundModel" bit is about generating suggestions by feeding the URL into our search engine)
In any action method that inherits the base, I can simply call this:
... whenever I catch an invalid parameter. And the catch-all route does the same.
在 Web 配置中进行设置:
error.html 是您的自定义页面,您可以向用户显示任意 HTML。
Set it up in the web config:
error.html is your custom page that you can have to display any arbitrary HTML to the user.
这是 ASP.NET MVC 框架的一大缺陷,因为你无法自定义(真正的自定义,我的意思不仅仅是任何东西的一个错误页面)404 页面,没有像 1 个答案。您可以对所有未找到的原因使用一个 404 错误,也可以通过 [HandleError] 自定义多个 500 错误页面,但不能以声明方式自定义 404 错误。由于 SEO 原因,500 个错误是不好的。 404 错误是好错误。
It's big miss from ASP.NET MVC framework because you can't customize (real customization I mean not just-one-error-page-for-anything) 404 pages without "crunches" like 1 answer. You can use one 404 error for all not-found causes, or you can customize multiple 500 error pages via [HandleError], but you CAN NOT customize 404 errs declaratively. 500 errs are bad due to SEO reasons. 404 errs are good errs.