【问题标题】:Is there a way to enable custom errors in ASP MVC 4?有没有办法在 ASP MVC 4 中启用自定义错误?
【发布时间】:2017-12-25 03:14:28
【问题描述】:

我尝试了所有可能的方法,我在这里 (How to make custom error pages work in ASP.NET MVC 4) 或这里:http://benfoster.io/blog/aspnet-mvc-custom-error-pages,这里:http://www.secretgeek.net/custom_errors_mvc,但似乎没有一个对我有用。

我将它简化为最小,但在点击不存在的页面时仍然收到丑陋的标准错误消息。

我的 Error.cshtml 放在 Views\Shared 文件夹中,它看起来像:

<div>
    <span>Error occurred</span>
</div>

也试过了:

@model System.Web.Mvc.HandleErrorInfo
@{
    ViewBag.Title = "Parking & Ticket Scan Information - Error";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<div>
    <span>Error occurred</span>
</div>

我的 web.config 包含:

<customErrors mode="On" defaultRedirect="~/Error">
    <error redirect="~/Error/NotFound" statusCode="404" />
</customErrors>

但我也试过:

<customErrors mode="On" defaultRedirect="~/Error">
</customErrors>

我的 ErrorController 是这样的:

public class ErrorController : Controller
{
    [HandleError]
    public ViewResult Index()
    {
        return View();
    }
}

(有或无 [HandleError] 属性,有无

public ViewResult NotFound()
{
    Response.StatusCode = 404;  //you may want to set this to 200
    return View("NotFound");
}

后来我还在 Global.asax 中添加了路由:

routes.MapRoute( 名称:“PageNotFound”, 网址:“{*url}”, 默认值:new { controller = "Error", action = "Index", id = UrlParameter.Optional }

似乎没有什么可以强制 IIS 显示自定义错误。我还尝试了什么?当然注释掉了 filters.Add(new HandleErrorAttribute()); 将 Error.cshtml 移至 Views 文件夹。

我可以使用其他方法来启用它吗?

【问题讨论】:

  • 我已经尝试过 Ben Foster 的解决方案并且它有效。如果 IIS 首先截获错误,我尝试过的其他一些解决方案将不起作用——在这种情况下,您的应用将无法处理错误,您将看到默认错误。

标签: c# asp.net-mvc asp.net-mvc-4 custom-errors


【解决方案1】:

你总是可以做这样的事情

public class HandleUnauthorizedAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        base.OnException(filterContext);

        if (filterContext.Exception.GetType() != typeof (SecurityException)) return;

        var controllerName = (string) filterContext.RouteData.Values["controller"];
        var actionName = (string) filterContext.RouteData.Values["action"];
        var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);

        filterContext.Result = new ViewResult
        {
            ViewName = "Unauthorized",
            ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
            TempData = filterContext.Controller.TempData
        };
        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();
        filterContext.HttpContext.Response.StatusCode = 403;
        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    }
}

此代码捕获所有 SecurityExceptions 并路由到填充了 HandleErrorInfo 的自定义错误页面。

您始终可以为要捕获的任何异常创建单独的过滤器并将其路由到其他自定义错误页面。

然后在启动时注册过滤器

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleUnauthorizedAttribute());
        //more filters if you define them.
    }
}

并在 /Shared/Views 中创建您的视图

【讨论】:

    【解决方案2】:

    所以到目前为止我发现的唯一可能的解决方案是在View\Error 文件夹中添加一个与ErrorController 的操作方法名称相对应的视图。所有其他指南中似乎都缺少这个微小的细节。

    所以现在我有了 ErrorContoller.cs:

    public class ErrorController : Controller
    {
        public ActionResult ErrorDefault()
        {
            return View();
        }
    }
    

    Views\Error 文件夹中的 ErrorDefault.cshtml:

    @{
        ViewBag.Title = "ErrorDefault";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h2>ErrorDefault</h2>
    

    和 web.config:

    <customErrors mode="On" defaultRedirect="~/Error/ErrorDefault">
    </customErrors>
    

    如果您忘记将视图放在与控制器名称对应的子文件夹中,它将在 MVC 4.0 中不起作用。

    不需要在 RouteConfig 中添加单独的路由。

    我希望有人会发现这很有用。 :)

    【讨论】:

    • "如果您忘记将视图放在与控制器名称对应的子文件夹中,它将无法在 MVC 中工作" - 一直都是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-28
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 2016-09-13
    相关资源
    最近更新 更多