我用的是RC2

使用URL路由:

routes.MapRoute(
    "Error",
     "{*url}",
     new { controller = "Errors", action = "NotFound" }  // 404s
);

上面似乎照顾到这样的请求(假设默认路由表由最初的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);
}  

但是,前面的策略不处理对坏/未知控制器的请求。例如,我没有“/IDoNotExist”,如果我请求这个,我从web服务器得到通用404页面,而不是我的404,如果我使用路由+覆盖。

最后,我的问题是:有没有办法在MVC框架中使用路由或其他东西来捕获这种类型的请求?

或者我应该默认使用Web。配置customErrors作为我的404处理程序,忘记这一切?我假设如果我使用customErrors,由于Web的原因,我将不得不在/Views之外存储通用404页面。配置直接访问限制。


当前回答

我浏览了所有的文章,但没有一篇对我有用: 我的要求用户键入任何在您的url自定义404页面应该显示。我认为它非常直截了当。但是你应该正确理解404的处理:

 <system.web>
    <customErrors mode="On" redirectMode="ResponseRewrite">
      <error statusCode="404" redirect="~/PageNotFound.aspx"/>
    </customErrors>
  </system.web>
<system.webServer>
    <httpErrors errorMode="Custom">
      <remove statusCode="404"/>
      <error statusCode="404" path="/PageNotFound.html" responseMode="ExecuteURL"/>
    </httpErrors>
</system.webServer>

我发现这篇文章很有帮助。应该马上读。自定义错误页面- ben Foster

其他回答

我对未处理区域、控制器和动作的简化解决方案:

Create a view 404.cshtml. Create a base class for your controllers: 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"); } } Create a custom controller factory returning your base controller as a fallback: public class ControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { if (controllerType != null) return base.GetControllerInstance(requestContext, controllerType); return new Controller(); } } Add to Application_Start() the following line: ControllerBuilder.Current.SetControllerFactory(typeof(ControllerFactory));

ASP。NET MVC不太支持自定义404页面。自定义控制器工厂,捕获所有路由,带有HandleUnknownAction的基控制器类-啊!

到目前为止,IIS自定义错误页面是更好的选择:

. config

<system.webServer>
  <httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404" />
    <error statusCode="404" responseMode="ExecuteURL" path="/Error/PageNotFound" />
  </httpErrors>
</system.webServer>

ErrorController

public class ErrorController : Controller
{
    public ActionResult PageNotFound()
    {
        Response.StatusCode = 404;
        return View();
    }
}

示例项目

GitHub上的Test404 生活的网站

我真的很喜欢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
}

基本上,这将阻止包含无效动作和控制器的url两次触发异常例程。Eg的url,如asdfsdf/dfgdfgd

试试nuget上的NotFoundMVC。它可以工作,不需要设置。

加上我的解决方案,这几乎是相同的Herman Kan的,有一个小皱纹,让它工作在我的项目。

创建一个自定义错误控制器:

public class Error404Controller : BaseController
{
    [HttpGet]
    public ActionResult PageNotFound()
    {
        Response.StatusCode = 404;
        return View("404");
    }
}

然后创建一个自定义控制器工厂:

public class CustomControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        return controllerType == null ? new Error404Controller() : base.GetControllerInstance(requestContext, controllerType);
    }
}

最后,向自定义错误控制器添加一个覆盖:

protected override void HandleUnknownAction(string actionName)
{
    var errorRoute = new RouteData();
    errorRoute.Values.Add("controller", "Error404");
    errorRoute.Values.Add("action", "PageNotFound");
    new Error404Controller().Execute(new RequestContext(HttpContext, errorRoute));
}

就是这样。不需要网络。配置更改。