5

我正在努力了解如何正确处理 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...");
    }
}

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

<customErrors mode="On"></customErrors>

当我运行应用程序并单击“联系”时,我看到了预期的~/Views/Shared/Error.cshtml视图,因为我已HandleErrorAttribute注册为全局过滤器。

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


自定义错误配置

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

  • 一个很好的用户友好的自定义 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>

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

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

4

3 回答 3

16

ASP.NET 在内部使用 401 将用户重定向到登录页面。无论您打算在哪里抛出未经授权的 401,而不是抛出 403 禁止。

于 2012-11-28T14:52:49.620 回答
8

如果您确实需要返回 401 而不是 403,则可以使用:

HttpContext.Current.Response.SuppressFormsAuthenticationRedirect = true
于 2013-02-22T05:42:48.077 回答
5

我遇到了类似的问题,尽管更改了 web.config,但我无法获得 401 错误来访问我的页面。

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

对于我的项目,我编辑了 Global.asax 文件以重定向到我为 401 错误创建的路由,将用户发送到“未经授权查看此内容”视图。

在 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);
        }
    }

在 Route.config 中:

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

在控制器中:

    public ViewResult Unauthorised()
    {
        //Response.StatusCode = 401; // Do not set this or else you get a redirect loop
        return View();
    }
于 2014-02-10T16:50:59.017 回答