我很难理解如何正确处理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
的实例?
CustomErrors config
理想情况下,我想要以下自定义错误页面:
我创建了一个新的“错误”控制器,其中包含上述每个场景的视图。然后我在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页面。相反,当我尝试访问defaultRedirect
控制器上的About
操作时,我得到了〜/ Error / Trouble 视图(指定为Home
的视图) 。
为什么我的自定义401重定向页面无效?
答案 0 :(得分:16)
ASP.NET在内部使用401来将用户重定向到登录页面。无论你打算在未经授权的情况下扔掉401,都要禁止403。
答案 1 :(得分:8)
如果你真的需要返回401而不是403,那么你可以使用:
HttpContext.Current.Response.SuppressFormsAuthenticationRedirect = true
答案 2 :(得分: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);
}
}
并在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();
}