Rom*_*man 18 asp.net-mvc handleerror
我在ASP.NET MVC网站中实现了错误处理,就像建议这篇文章一样.
404错误一切正常.但如何正确显示用户友好的屏幕401错误?它们通常不会抛出可在内部处理的异常,Application_Error()
而是返回HttpUnauthorizedResult.一种可能的方法是将以下代码添加到Application_EndRequest()
方法的末尾
if (Context.Response.StatusCode == 401)
{
throw new HttpException(401, "You are not authorised");
// or UserFriendlyErrorRedirect(new HttpException(401, "You are not authorised")), witout exception
}
Run Code Online (Sandbox Code Playgroud)
但在Application_EndRequest()
Context.Session == null中,errorController.Execute()
失败是因为它无法使用默认的TempDataProvider.
// Call target Controller and pass the routeData.
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(
new HttpContextWrapper(Context), routeData)); // Additional information: The SessionStateTempDataProvider requires SessionState to be enabled.
Run Code Online (Sandbox Code Playgroud)
那么,您能否建议一些最佳实践如何在ASP.NET MVC应用程序中使用"用户友好句柄"401?
谢谢.
小智 14
查看HandleErrorAttribute.从中子类或添加您自己的实现,它将处理您感兴趣的所有状态代码.您可以使它为每种错误类型返回单独的错误视图.
以下是如何创建句柄错误异常过滤器的想法.我抛弃了大部分内容,只专注于我们的必需品.绝对看看原始实现添加参数检查和其他重要的事情.
public class HandleManyErrorsAttribute : FilterAttribute, IExceptionFilter
{
public virtual void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
return;
Exception exception = filterContext.Exception;
string viewName = string.Empty;
object viewModel = null;
int httpCode = new HttpException(null, exception).GetHttpCode();
if (httpCode == 500)
{
viewName = "Error500View";
viewModel = new Error500Model();
}
else if (httpCode == 404)
{
viewName = "Error404View";
viewModel = new Error404Model();
}
else if (httpCode == 401)
{
viewName = "Error401View";
viewModel = new Error401Model();
}
string controllerName = (string)filterContext.RouteData.Values["controller"];
string actionName = (string)filterContext.RouteData.Values["action"];
filterContext.Result = new ViewResult
{
ViewName = viewName,
MasterName = Master,
ViewData = viewModel,
TempData = filterContext.Controller.TempData
};
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = httpCode;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
Run Code Online (Sandbox Code Playgroud)
然后用这个属性"装饰"你的控制器动作:
[HandleManyErrors]
public ActionResult DoSomethingBuggy ()
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
我设法以一种非常简单的方式解决了这个问题.我想为登录用户显示一个自定义页面("你没有权限bla bla ...")并将未经身份验证的用户重定向到登录页面(默认行为).所以我实现了一个自定义的AuthorizeAttribute(比如CustomAuthorizeAttribute),其HandleUnauthorizedRequest方法被覆盖,如果用户通过身份验证,我将filterContext参数的Result属性设置为一个名为AccessDenied.aspx的ViewResult(在Shared文件夹中)
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
base.HandleUnauthorizedRequest(filterContext);
}
else
{
filterContext.Result = new ViewResult { ViewName = "AccessDenied" };
}
}
Run Code Online (Sandbox Code Playgroud)
然后你必须使用这个新属性.问候.
归档时间: |
|
查看次数: |
14039 次 |
最近记录: |