我在ASP.NET MVC site
in a way like suggests this post中实现了错误处理.
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 }
但在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?
谢谢.
解决方法
看看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 () { // ... }