我已经在ASP.NET MVC site in a way like suggests this post中实现了错误处理。
有了404个错误,一切都能正常工作。但是如何正确地为401 error显示用户友好的屏幕?它们通常不会抛出可以在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
}
但在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.
那么,你能推荐一些在ASP.NET MVC应用程序中如何“用户友好处理”401的最佳实践吗?
谢谢。
发布于 2009-11-05 19:20:51
看看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;
}
}
然后你用这个属性来“装饰”你的控制器动作:
[HandleManyErrors]
public ActionResult DoSomethingBuggy ()
{
// ...
}
发布于 2010-01-22 20:54:52
我设法用一种非常简单的方式解决了这个问题。我想为登录的用户显示一个自定义页面(“您没有权限...”)并将未经验证的用户重定向到登录页面(默认行为)。因此,我使用HandleUnauthorizedRequest方法实现了一个自定义结果(比如CustomAuthorizeAttribute),如果用户通过了身份验证,则使用名为AccessDenied.aspx的ViewResult (在共享文件夹中)设置filterContext参数的Result属性
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
base.HandleUnauthorizedRequest(filterContext);
}
else
{
filterContext.Result = new ViewResult { ViewName = "AccessDenied" };
}
}
然后,您必须使用这个新属性。致以问候。
发布于 2009-11-05 19:40:41
如果您正在使用IIS,那么您很可能会使用ASP.NET,那么为什么不设置IIS来对该Web应用程序/虚拟目录使用您的自定义401error页面呢?
https://stackoverflow.com/questions/1679881
复制相似问题