Bri*_*ian 426 asp.net-mvc http-status-code-404
我正在使用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页面.
小智 264
代码来自http://blogs.microsoft.co.il/blogs/shay/archive/2009/03/06/real-world-error-hadnling-in-asp-net-mvc-rc2.aspx并且有效在ASP.net MVC 1.0中也是如此
以下是我处理http异常的方法:
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
// Log the exception.
ILogger logger = Container.Resolve<ILogger>();
logger.Error(exception);
Response.Clear();
HttpException httpException = exception as HttpException;
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
if (httpException == null)
{
routeData.Values.Add("action", "Index");
}
else //It's an Http Exception, Let's handle it.
{
switch (httpException.GetHttpCode())
{
case 404:
// Page not found.
routeData.Values.Add("action", "HttpError404");
break;
case 500:
// Server error.
routeData.Values.Add("action", "HttpError500");
break;
// Here you can handle Views to other error codes.
// I choose a General error template
default:
routeData.Values.Add("action", "General");
break;
}
}
// Pass exception details to the target error View.
routeData.Values.Add("error", exception);
// Clear the error on server.
Server.ClearError();
// Avoid IIS7 getting in the middle
Response.TrySkipIisCustomErrors = true;
// Call target Controller and pass the routeData.
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(
new HttpContextWrapper(Context), routeData));
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*caj 253
以下是我对404解决方案的要求,下面我将展示如何实现它:
我认为你应该Application_Error在Global.asax中保存更高级的东西,比如未处理的异常和日志记录(比如Shay Jacoby的答案显示),但不是404处理.这就是为什么我的建议将404内容保留在Global.asax文件之外的原因.
这是可维护性的好主意.使用ErrorController,以便您对精心设计的404页面的未来改进可以轻松适应.另外,请确保您的回复包含404代码!
public class ErrorController : MyController
{
#region Http404
public ActionResult Http404(string url)
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
var model = new NotFoundViewModel();
// If the url is relative ('NotFound' route) then replace with Requested path
model.RequestedUrl = Request.Url.OriginalString.Contains(url) & Request.Url.OriginalString != url ?
Request.Url.OriginalString : url;
// Dont get the user stuck in a 'retry loop' by
// allowing the Referrer to be the same as the Request
model.ReferrerUrl = Request.UrlReferrer != null &&
Request.UrlReferrer.OriginalString != model.RequestedUrl ?
Request.UrlReferrer.OriginalString : null;
// TODO: insert ILogger here
return View("NotFound", model);
}
public class NotFoundViewModel
{
public string RequestedUrl { get; set; }
public string ReferrerUrl { get; set; }
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
HandleUnknownActionASP.NET MVC中的404s需要在很多地方被捕获.首先是HandleUnknownAction.
该InvokeHttp404方法为重新路由到ErrorController我们的新Http404操作创建了一个公共位置.想想干!
public abstract class MyController : Controller
{
#region Http404 handling
protected override void HandleUnknownAction(string actionName)
{
// If controller is ErrorController dont 'nest' exceptions
if (this.GetType() != typeof(ErrorController))
this.InvokeHttp404(HttpContext);
}
public ActionResult InvokeHttp404(HttpContextBase httpContext)
{
IController errorController = ObjectFactory.GetInstance<ErrorController>();
var errorRoute = new RouteData();
errorRoute.Values.Add("controller", "Error");
errorRoute.Values.Add("action", "Http404");
errorRoute.Values.Add("url", httpContext.Request.Url.OriginalString);
errorController.Execute(new RequestContext(
httpContext, errorRoute));
return new EmptyResult();
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
像这样(它不一定是StructureMap):
MVC1.0示例:
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
try
{
if (controllerType == null)
return base.GetControllerInstance(controllerType);
}
catch (HttpException ex)
{
if (ex.GetHttpCode() == (int)HttpStatusCode.NotFound)
{
IController errorController = ObjectFactory.GetInstance<ErrorController>();
((ErrorController)errorController).InvokeHttp404(RequestContext.HttpContext);
return errorController;
}
else
throw ex;
}
return ObjectFactory.GetInstance(controllerType) as Controller;
}
}
Run Code Online (Sandbox Code Playgroud)
MVC2.0示例:
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
try
{
if (controllerType == null)
return base.GetControllerInstance(requestContext, controllerType);
}
catch (HttpException ex)
{
if (ex.GetHttpCode() == 404)
{
IController errorController = ObjectFactory.GetInstance<ErrorController>();
((ErrorController)errorController).InvokeHttp404(requestContext.HttpContext);
return errorController;
}
else
throw ex;
}
return ObjectFactory.GetInstance(controllerType) as Controller;
}
Run Code Online (Sandbox Code Playgroud)
我认为更好地捕捉到更接近它们起源的错误.这就是为什么我更喜欢上面的Application_Error处理程序.
这是第二个捕获404s的地方.
这条路线应该指向我们的Http404行动.请注意,urlparam将是一个相对URL,因为路由引擎正在剥离域部分?这就是我们在步骤1中拥有所有条件URL逻辑的原因.
routes.MapRoute("NotFound", "{*url}",
new { controller = "Error", action = "Http404" });
Run Code Online (Sandbox Code Playgroud)
这是在你自己不调用的MVC应用程序中捕获404s的第三个也是最后一个.如果你没有在这里捕获不匹配的路由,那么MVC会将问题传递给ASP.NET(Global.asax),在这种情况下你真的不想要它.
就像将错误的ID提交给我的Loans控制器(源自MyController):
//
// GET: /Detail/ID
public ActionResult Detail(int ID)
{
Loan loan = this._svc.GetLoans().WithID(ID);
if (loan == null)
return this.InvokeHttp404(HttpContext);
else
return View(loan);
}
Run Code Online (Sandbox Code Playgroud)
如果所有这些都可以用更少的代码连接在更少的地方,那将是很好的,但我认为这个解决方案更易于维护,更可测试且相当实用.
感谢您的反馈到目前为止.我想要得到更多.
注意:这已经根据我的原始答案进行了大量编辑,但目的/要求是相同的 - 这就是我没有添加新答案的原因
Pav*_*uva 232
ASP.NET MVC不能很好地支持自定义404页面.定制控制器工厂,全能路线,基础控制器类HandleUnknownAction- 唉!
到目前为止,IIS自定义错误页面是更好的选择
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error statusCode="404" responseMode="ExecuteURL" path="/Error/PageNotFound" />
</httpErrors>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)
public class ErrorController : Controller
{
public ActionResult PageNotFound()
{
Response.StatusCode = 404;
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
Pur*_*ome 153

对于那里的懒人:
Install-Package MagicalUnicornMvcErrorToolkit -Version 1.0
Run Code Online (Sandbox Code Playgroud)
然后从中删除此行 global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
Run Code Online (Sandbox Code Playgroud)
这仅适用于IIS7 +和IIS Express.
如果你正在使用卡西尼......那么......嗯..呃......尴尬......

我知道这已经回答了.但答案真的很简单(为David Fowler和Damian Edwards欢呼,真的回答这个问题).
有没有必要做任何定制.
因为ASP.NET MVC3,所有的零碎都在那里.
<system.web>
<customErrors mode="On" defaultRedirect="/ServerError">
<error statusCode="404" redirect="/NotFound" />
</customErrors>
Run Code Online (Sandbox Code Playgroud)
和
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" path="/NotFound" responseMode="ExecuteURL" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="500" path="/ServerError" responseMode="ExecuteURL" />
</httpErrors>
...
<system.webServer>
...
</system.web>
Run Code Online (Sandbox Code Playgroud)
现在请仔细注意我决定使用的路线.你可以使用任何东西,但我的路线是
/NotFound < - 找不到404,错误页面./ServerError< - 对于任何其他错误,包括我的代码中发生的错误.这是500内部服务器错误看看第一部分中<system.web>只有一个自定义条目?这个statusCode="404"条目?我只列出了一个状态代码,因为所有其他错误,包括500 Server Error(即,当您的代码有错误并崩溃用户的请求时发生的那些讨厌的错误)..所有其他错误由设置处理defaultRedirect="/ServerError"... ,如果您没有找到404页面,请转到该路线/ServerError.
好.这是不合适的..现在我的路线列出来了global.asax
这是我的完整路线部分..
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new {favicon = @"(.*/)?favicon.ico(/.*)?"});
routes.MapRoute(
"Error - 404",
"NotFound",
new { controller = "Error", action = "NotFound" }
);
routes.MapRoute(
"Error - 500",
"ServerError",
new { controller = "Error", action = "ServerError"}
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional}
);
}
Run Code Online (Sandbox Code Playgroud)
这列出了两个忽略路由 - > axd's和favicons(ooo!bonus ignore route,for you!)然后(并且命令是IMPERATIVE HERE),我有两个显式的错误处理路由..后跟任何其他路由.在这种情况下,默认值为1.当然,我有更多,但这对我的网站来说很特别.只需确保错误路由位于列表顶部.秩序是必要的.
最后,当我们在global.asax文件中时,我们不会全局注册HandleError属性.不,不,不,先生.Nadda.不.粘.负.Noooooooooo ...
从中删除此行 global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
Run Code Online (Sandbox Code Playgroud)
现在..我们添加一个带有两种动作方法的控制器......
public class ErrorController : Controller
{
public ActionResult NotFound()
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
public ActionResult ServerError()
{
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
// Todo: Pass the exception into the view model, which you can make.
// That's an exercise, dear reader, for -you-.
// In case u want to pass it to the view, if you're admin, etc.
// if (User.IsAdmin) // <-- I just made that up :) U get the idea...
// {
// var exception = Server.GetLastError();
// // etc..
// }
return View();
}
// Shhh .. secret test method .. ooOOooOooOOOooohhhhhhhh
public ActionResult ThrowError()
{
throw new NotImplementedException("Pew ^ Pew");
}
}
Run Code Online (Sandbox Code Playgroud)
好的,我们来看看吧.首先,这里没有 [HandleError]属性.为什么?因为内置ASP.NET框架已经处理错误而且我们已经指定了我们需要做的所有狗屎来处理错误:)这是在这个方法中!
接下来,我有两个动作方法.那里没什么难的.如果您希望显示任何异常信息,那么您可以使用Server.GetLastError()获取该信息.
奖金WTF:是的,我做了第三个动作方法,测试错误处理.
最后,创建两个视图.将em放在普通视点中,对于此控制器.

Application_Error(object sender, EventArgs e)那个,我的朋友,应该是它.
现在,恭喜阅读这篇文章并获得独角兽作为奖品!

Mar*_*rco 85
我调查了很多关于如何在MVC妥善管理404 (具体MVC3) ,这一点,恕我直言,是最好的解决方案,我想出来的:
在global.asax中:
public class MvcApplication : HttpApplication
{
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 404)
{
Response.Clear();
var rd = new RouteData();
rd.DataTokens["area"] = "AreaName"; // In case controller is in another area
rd.Values["controller"] = "Errors";
rd.Values["action"] = "NotFound";
IController c = new ErrorsController();
c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
}
}
}
Run Code Online (Sandbox Code Playgroud)
ErrorsController:
public sealed class ErrorsController : Controller
{
public ActionResult NotFound()
{
ActionResult result;
object model = Request.Url.PathAndQuery;
if (!Request.IsAjaxRequest())
result = View(model);
else
result = PartialView("_NotFound", model);
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
(可选的)
说明:
AFAIK,ASP.NET MVC3应用程序可以生成404的6种不同情况.
(由ASP.NET Framework自动生成:)
(1) URL在路由表中找不到匹配项.
(由ASP.NET MVC框架自动生成:)
(2) URL在路由表中查找匹配项,但指定不存在的控制器.
(3) URL在路由表中查找匹配项,但指定不存在的操作.
(手动生成:)
(4)动作使用方法HttpNotFound()返回HttpNotFoundResult.
(5)一个动作抛出一个状态码为404的HttpException.
(6)动作手动将Response.StatusCode属性修改为404.
通常,您希望实现3个目标:
(1)向用户显示自定义404错误页面.
(2)维护客户端响应的404状态代码(对SEO特别重要).
(3)直接发送响应,不涉及302重定向.
有多种方法可以尝试实现此目的:
(1)
<system.web>
<customErrors mode="On">
<error statusCode="404" redirect="~/Errors/NotFound"/>
</customError>
</system.web>
Run Code Online (Sandbox Code Playgroud)
此解决方案的问题:
(2)
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="App/Errors/NotFound" responseMode="ExecuteURL"/>
</httpErrors>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)
此解决方案的问题:
(3)
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404"/>
<error statusCode="404" path="App/Errors/NotFound" responseMode="ExecuteURL"/>
</httpErrors>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)
此解决方案的问题:
(4)
<system.web>
<customErrors mode="On">
<error statusCode="404" redirect="~/Errors/NotFound"/>
</customError>
</system.web>
Run Code Online (Sandbox Code Playgroud)
和
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="App/Errors/NotFound" responseMode="ExecuteURL"/>
</httpErrors>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)
此解决方案的问题:
在尝试创建自己的库之前,对此感到困扰的人们(请参阅http://aboutcode.net/2011/02/26/handling-not-found-with-asp-net-mvc3.html).但是之前的解决方案似乎涵盖了所有情况,而没有使用外部库的复杂性.
Dav*_*owe 13
我真的很喜欢cottsaks解决方案,并认为它非常清楚地解释.我唯一的补充是如下改变第2步
public abstract class MyController : Controller
{
#region Http404 handling
protected override void HandleUnknownAction(string actionName)
{
//if controller is ErrorController dont 'nest' exceptions
if(this.GetType() != typeof(ErrorController))
this.InvokeHttp404(HttpContext);
}
public ActionResult InvokeHttp404(HttpContextBase httpContext)
{
IController errorController = ObjectFactory.GetInstance<ErrorController>();
var errorRoute = new RouteData();
errorRoute.Values.Add("controller", "Error");
errorRoute.Values.Add("action", "Http404");
errorRoute.Values.Add("url", httpContext.Request.Url.OriginalString);
errorController.Execute(new RequestContext(
httpContext, errorRoute));
return new EmptyResult();
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
基本上,这会阻止包含无效操作和控制器的URL触发异常例程两次.例如,对于诸如asdfsdf/dfgdfgd之类的URL
我可以获得@ cottsak的方法来处理无效控制器的唯一方法是修改CustomControllerFactory中的现有路由请求,如下所示:
public class CustomControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
try
{
if (controllerType == null)
return base.GetControllerInstance(requestContext, controllerType);
else
return ObjectFactory.GetInstance(controllerType) as Controller;
}
catch (HttpException ex)
{
if (ex.GetHttpCode() == (int)HttpStatusCode.NotFound)
{
requestContext.RouteData.Values["controller"] = "Error";
requestContext.RouteData.Values["action"] = "Http404";
requestContext.RouteData.Values.Add("url", requestContext.HttpContext.Request.Url.OriginalString);
return ObjectFactory.GetInstance<ErrorController>();
}
else
throw ex;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我应该提到我正在使用MVC 2.0.
这是使用 MVC 工具的另一种方法,您可以处理对错误控制器名称、错误路由名称以及您认为适合 Action 方法内部的任何其他条件的请求。就我个人而言,我更喜欢避免尽可能多的 web.config 设置,因为它们执行 302 / 200 重定向,并且不支持Server.Transfer使用 Razor 视图的 ResponseRewrite ( )。出于 SEO 原因,我更愿意返回带有自定义错误页面的 404。
其中一些是对上述 cottsak 技术的新运用。
此解决方案还使用有利于 MVC 3 错误过滤器的最小 web.config 设置。
只需从操作或自定义 ActionFilterAttribute 抛出 HttpException。
Throw New HttpException(HttpStatusCode.NotFound, "[Custom Exception Message Here]")
Run Code Online (Sandbox Code Playgroud)
将以下设置添加到您的 web.config。这是使用 MVC 的 HandleErrorAttribute 所必需的。
<customErrors mode="On" redirectMode="ResponseRedirect" />
Run Code Online (Sandbox Code Playgroud)
添加与 MVC 框架的 HandleErrorAttribute 类似的自定义 HandleHttpErrorAttribute,但 HTTP 错误除外:
<AttributeUsage(AttributeTargets.All, AllowMultiple:=True)>
Public Class HandleHttpErrorAttribute
Inherits FilterAttribute
Implements IExceptionFilter
Private Const m_DefaultViewFormat As String = "ErrorHttp{0}"
Private m_HttpCode As HttpStatusCode
Private m_Master As String
Private m_View As String
Public Property HttpCode As HttpStatusCode
Get
If m_HttpCode = 0 Then
Return HttpStatusCode.NotFound
End If
Return m_HttpCode
End Get
Set(value As HttpStatusCode)
m_HttpCode = value
End Set
End Property
Public Property Master As String
Get
Return If(m_Master, String.Empty)
End Get
Set(value As String)
m_Master = value
End Set
End Property
Public Property View As String
Get
If String.IsNullOrEmpty(m_View) Then
Return String.Format(m_DefaultViewFormat, Me.HttpCode)
End If
Return m_View
End Get
Set(value As String)
m_View = value
End Set
End Property
Public Sub OnException(filterContext As System.Web.Mvc.ExceptionContext) Implements System.Web.Mvc.IExceptionFilter.OnException
If filterContext Is Nothing Then Throw New ArgumentException("filterContext")
If filterContext.IsChildAction Then
Return
End If
If filterContext.ExceptionHandled OrElse Not filterContext.HttpContext.IsCustomErrorEnabled Then
Return
End If
Dim ex As HttpException = TryCast(filterContext.Exception, HttpException)
If ex Is Nothing OrElse ex.GetHttpCode = HttpStatusCode.InternalServerError Then
Return
End If
If ex.GetHttpCode <> Me.HttpCode Then
Return
End If
Dim controllerName As String = filterContext.RouteData.Values("controller")
Dim actionName As String = filterContext.RouteData.Values("action")
Dim model As New HandleErrorInfo(filterContext.Exception, controllerName, actionName)
filterContext.Result = New ViewResult With {
.ViewName = Me.View,
.MasterName = Me.Master,
.ViewData = New ViewDataDictionary(Of HandleErrorInfo)(model),
.TempData = filterContext.Controller.TempData
}
filterContext.ExceptionHandled = True
filterContext.HttpContext.Response.Clear()
filterContext.HttpContext.Response.StatusCode = Me.HttpCode
filterContext.HttpContext.Response.TrySkipIisCustomErrors = True
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
将过滤器添加到 中的 GlobalFilterCollection( GlobalFilters.Filters) 中Global.asax。此示例会将所有 InternalServerError (500) 错误路由到错误共享视图 ( Views/Shared/Error.vbhtml)。NotFound (404) 错误也将发送到共享视图中的 ErrorHttp404.vbhtml。我在此处添加了 401 错误,以向您展示如何针对其他 HTTP 错误代码进行扩展。请注意,这些必须是共享视图,并且它们都使用System.Web.Mvc.HandleErrorInfo对象作为模型。
filters.Add(New HandleHttpErrorAttribute With {.View = "ErrorHttp401", .HttpCode = HttpStatusCode.Unauthorized})
filters.Add(New HandleHttpErrorAttribute With {.View = "ErrorHttp404", .HttpCode = HttpStatusCode.NotFound})
filters.Add(New HandleErrorAttribute With {.View = "Error"})
Run Code Online (Sandbox Code Playgroud)
创建一个基本控制器类并在控制器中继承它。此步骤允许我们处理未知的操作名称并向我们的 HandleHttpErrorAttribute 引发 HTTP 404 错误。
Public Class BaseController
Inherits System.Web.Mvc.Controller
Protected Overrides Sub HandleUnknownAction(actionName As String)
Me.ActionInvoker.InvokeAction(Me.ControllerContext, "Unknown")
End Sub
Public Function Unknown() As ActionResult
Throw New HttpException(HttpStatusCode.NotFound, "The specified controller or action does not exist.")
Return New EmptyResult
End Function
End Class
Run Code Online (Sandbox Code Playgroud)
创建一个 ControllerFactory 覆盖,并在 Application_Start 的 Global.asax 文件中覆盖它。此步骤允许我们在指定无效的控制器名称时引发 HTTP 404 异常。
Public Class MyControllerFactory
Inherits DefaultControllerFactory
Protected Overrides Function GetControllerInstance(requestContext As System.Web.Routing.RequestContext, controllerType As System.Type) As System.Web.Mvc.IController
Try
Return MyBase.GetControllerInstance(requestContext, controllerType)
Catch ex As HttpException
Return DependencyResolver.Current.GetService(Of BaseController)()
End Try
End Function
End Class
'In Global.asax.vb Application_Start:
controllerBuilder.Current.SetControllerFactory(New MyControllerFactory)
Run Code Online (Sandbox Code Playgroud)
在 RoutTable.Routes 中包含一条用于 BaseController Unknown 操作的特殊路由。这将帮助我们在用户访问未知控制器或未知操作的情况下引发 404。
'BaseController
routes.MapRoute( _
"Unknown", "BaseController/{action}/{id}", _
New With {.controller = "BaseController", .action = "Unknown", .id = UrlParameter.Optional} _
)
Run Code Online (Sandbox Code Playgroud)
此示例演示了如何使用 MVC 框架将 404 Http 错误代码返回到浏览器,而无需使用筛选器属性和共享错误视图进行重定向。它还演示了在指定无效的控制器名称和操作名称时显示相同的自定义错误页面。
如果我获得足够的票数来发布一个,我将添加无效控制器名称、操作名称和从 Home/TriggerNotFound 操作引发的自定义 404 的屏幕截图 =)。当我使用此解决方案访问以下 URL 时,Fiddler 返回 404 消息:
/InvalidController
/Home/InvalidRoute
/InvalidController/InvalidRoute
/Home/TriggerNotFound
Run Code Online (Sandbox Code Playgroud)
cottsak 的上述帖子和这些文章都是很好的参考。
我的缩短解决方案适用于未处理的区域、控制器和操作:
创建视图404.cshtml。
为您的控制器创建一个基类:
public class Controller : System.Web.Mvc.Controller
{
protected override void HandleUnknownAction(string actionName)
{
Http404().ExecuteResult(ControllerContext);
}
protected virtual ViewResult Http404()
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View("404");
}
}
Run Code Online (Sandbox Code Playgroud)创建一个自定义控制器工厂,返回您的基本控制器作为后备:
public class ControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType != null)
return base.GetControllerInstance(requestContext, controllerType);
return new Controller();
}
}
Run Code Online (Sandbox Code Playgroud)添加到Application_Start()以下行:
ControllerBuilder.Current.SetControllerFactory(typeof(ControllerFactory));
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
132488 次 |
| 最近记录: |