针对404,401和其他异常的ASP.NET MVC4错误处理

Mat*_*son 5 asp.net asp.net-mvc

我很难理解如何正确处理ASP.NET MVC4中的错误.作为一个例子,我使用"Internet应用程序"模板创建了一个新的MVC4项目,并更新了我的家庭控制器以测试一些错误情况:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Hello";
        return View();
    }

    public ActionResult About()
    {
        throw new HttpException(401, "Not Authorized");
    }

    public ActionResult Contact()
    {
        throw new Exception("Oh no, some error occurred...");
    }
}
Run Code Online (Sandbox Code Playgroud)

我在web.config文件中启用了customErrors:

<customErrors mode="On"></customErrors>
Run Code Online (Sandbox Code Playgroud)

当我运行的应用程序,然后单击"联系人",我看到了〜/查看/共享/ Error.cshtml如预期看法,因为我已经在HandleErrorAttribute注册成为一个全球性的过滤器.

但是,当我单击"关于"时,我得到标准的ASP.NET黄色错误页面,上面写着"运行时错误".为什么这两个异常的处理方式不同?如何HttpException使用该HandleError属性获取被捕获的实例?


CustomErrors配置

理想情况下,我想要以下自定义错误页面:

  • 一个自定义的404(未找到)页面,它很好用户友好
  • 自定义401(未授权)页面,通知用户他们没有访问权限(例如,在检查模型中特定项目的权限后抛出)
  • 在所有其他情况下使用的通用错误页面(代替标准的黄色ASP.NET页面).

我创建了一个新的"错误"控制器,其中包含上述每个场景的视图.然后我在web.config中更新了customErrors,如下所示:

<customErrors mode="On" defaultRedirect="~/Error/Trouble">
    <error statusCode="404" redirect="~/Error/NotFound"></error>
    <error statusCode="401" redirect="~/Error/NotAuthorized"></error>
</customErrors>
Run Code Online (Sandbox Code Playgroud)

404页面工作正常,但我根本没有得到401页面.相反,当我尝试访问控制器上的操作时,我得到〜/ Error/Trouble视图(指定为的视图defaultRedirect).AboutHome

为什么我的自定义401重定向页面不起作用?

dan*_*wig 16

ASP.NET在内部使用401来将用户重定向到登录页面.无论你打算在未经授权的情况下扔掉401,都要禁止403.


Mon*_*eur 8

如果你真的需要返回401而不是403,那么你可以使用:

HttpContext.Current.Response.SuppressFormsAuthenticationRedirect = true
Run Code Online (Sandbox Code Playgroud)


Vic*_*ber 5

我遇到了类似的问题,即使对web.config进行了更改,我也无法将401错误转到我的页面.

对于401,您可能会看到标准的401 Unauthorized页面,即使您已将401添加到web.config中的customersrors部分.我读到,当使用IIS和Windows身份验证时,检查会在ASP.NET甚至看到请求之前发生,因此您会看到它自己的401.

对于我的项目,我编辑了Global.asax文件以重定向到我为401错误创建的路由,将用户发送到"Unauthorized to see this"视图.

在Global.asax中:

    void Application_EndRequest(object sender, System.EventArgs e)
    {
        // If the user is not authorised to see this page or access this function, send them to the error page.
        if (Response.StatusCode == 401)
        {
            Response.ClearContent();
            Response.RedirectToRoute("ErrorHandler", (RouteTable.Routes["ErrorHandler"] as Route).Defaults);
        }
    }
Run Code Online (Sandbox Code Playgroud)

并在Route.config中:

        routes.MapRoute(
        "ErrorHandler",
        "Error/{action}/{errMsg}",
        new { controller = "Error", action = "Unauthorised", errMsg = UrlParameter.Optional }
        );
Run Code Online (Sandbox Code Playgroud)

并在控制器中:

    public ViewResult Unauthorised()
    {
        //Response.StatusCode = 401; // Do not set this or else you get a redirect loop
        return View();
    }
Run Code Online (Sandbox Code Playgroud)