代码之家  ›  专栏  ›  技术社区  ›  Roman

ASP.NET MVC用户友好401错误

  •  18
  • Roman  · 技术社区  · 16 年前

    我在ASP.NET MVC站点中实现了错误处理 in a way like suggests this post .

    有404个错误,一切正常。但如何正确显示用户友好的屏幕 401误差 ?他们通常不会抛出可以在内部处理的异常 Application_Error() 但相反,action返回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
    }
    

    但里面 应用程序结束请求() context.session==空, 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?

    谢谢。

    4 回复  |  直到 10 年前
        1
  •  14
  •   user151323    16 年前

    看看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 ()
    {
        // ...
    }
    
        2
  •  6
  •   uvita    16 年前

    我设法用一种非常简单的方法解决了这个问题。我想为登录用户显示一个自定义页面(“您没有权限bla bla…”)并将未经身份验证的用户重定向到登录页面(默认行为)。 因此,我实现了一个自定义authorizeattribute(比如custom authorizeattribute),用一种重写handleUnauthorizedRequest方法的方式来实现:如果对用户进行了身份验证,我将使用名为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" };
        }
    }
    

    然后您必须使用这个新属性。 当做。

        3
  •  0
  •   Tamas Czinege    16 年前

    如果您使用的是ASP.NET MVC,那么您很可能会使用IIS,那么为什么不将IIS设置为使用Web应用程序/虚拟目录的自定义401错误页呢?

        4
  •  -1
  •   Community Mohan Dere    9 年前

    在我的一个项目中,我使用来自 uvita .

    我有 ASP.NET MVC2 我用 Active Directory(Active Directory) 没有登录页的身份验证。 我有一个 noauth.aspx文件 使用网站母版页的网页,集成Web应用程序布局。

    这是web.config。

    <system.web>
        <authentication mode="Windows" />
        <roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
           <providers>
              <clear />
              <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider"
              applicationName="/" />
          </providers>
        </roleManager>
    </system.web>
    

    新类CustomAutoizeAttribute

    using System.Web.Mvc;
    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
            else
            {
               filterContext.Result = new ViewResult { ViewName = "NoAuth"};
            }
        }
    }
    

    和管制员

    [CustomAuthorize(Roles = "ADRole")]
    public class HomeController : Controller
    {
        public HomeController()
        {
        }
    }
    
    推荐文章