Asp.net
ASP.NET MVC - 如何拋出類似於 StackOverflow 上的 404 頁面
我目前有一個繼承自
System.Web.Mvc.Controller. 在那個類上,我有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 不變(即:不重定向到任何其他頁面),而只是顯示“NotFound”視圖並將其推
HttpStatusCode.NotFound送到客戶端。例如,只需訪問https://stackoverflow.com/asdf,您將在其中看到自定義 404 頁面並查看完整的 URL。
顯然我錯過了一些東西,但我無法弄清楚。由於“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我的“未找到”路線什麼也沒做。
在我的另一個 SO question 上找到了我的答案。非常感謝Anh-Kiet Ngo的解決方案。
protected void Application_Error(object sender, EventArgs e) { Exception exception = Server.GetLastError(); // A good location for any error logging, otherwise, do it inside of the error controller. Response.Clear(); HttpException httpException = exception as HttpException; RouteData routeData = new RouteData(); routeData.Values.Add("controller", "YourErrorController"); if (httpException != null) { if (httpException.GetHttpCode() == 404) { routeData.Values.Add("action", "YourErrorAction"); // We can pass the exception to the Action as well, something like // routeData.Values.Add("error", exception); // Clear the error, otherwise, we will always get the default error page. Server.ClearError(); // Call the controller with the route IController errorController = new ApplicationName.Controllers.YourErrorController(); errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); } } }