分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

mvc的filter

发布时间:2023-09-06 01:16责任编辑:顾先生关键词:暂无标签

如果想要记录ajax的请求和输出信息、内部发生异常记录日志、需要登录认证、需要权限判断;那mvc的各种filter可以帮助你实现你想要的。Mvc框架支持5种不同类型的过滤器;我会按照执行顺序进行简单的demo,再简单的代码分享,万一对一个人有益,也是值的。

1.通过实现IAuthenticationFilter来进行登录认证,如果认证通过继续后续的权限授权等操作;如果认证没有通过跳转登录页面;代码如下:

public class MvcAuthenticationFilter : FilterAttribute, IAuthenticationFilter ???{ ???????/// <summary> ???????/// 是否需要认证 ????????/// </summary> ???????public bool IsNeedAuthentication { get; set; } ???????/// <summary> ???????/// 对请求进行身份验证 ???????/// </summary> ???????/// <param name="filterContext"></param> ???????public void OnAuthentication(AuthenticationContext filterContext) ???????{ ???????????bool flag = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true); ???????????if (flag) ???????????{ ???????????????return; ???????????} ???????????if (IsNeedAuthentication) ???????????{ ???????????????IPrincipal user; ???????????????if (this.IsAuthenticated(filterContext, out user)) ???????????????{ ???????????????????filterContext.Principal = user; ???????????????} ???????????????else ???????????????{ ???????????????????this.UnauthenticatedRequest(filterContext); ???????????????} ???????????} ???????} ???????protected bool IsAuthenticated(AuthenticationContext filterContext, out IPrincipal user) ???????{ ???????????user = filterContext.HttpContext.User; ???????????var cc = filterContext.Controller.ControllerContext.Controller as BaseController; ???????????if (cc != null && cc.CurrentAdminInfo != null) ???????????{ ???????????????IIdentity identity = user.Identity; ???????????????user = new GenericPrincipal(identity, new[] { "root", "noroot" }); //这里根据实际情况获取用户的角色 ???????????????return true; ???????????} ???????????return false; ???????} ???????protected void UnauthenticatedRequest(AuthenticationContext filterContext) ???????{ ???????????string returnUrl = filterContext.HttpContext.Request.Url.AbsolutePath; ???????????string redirectUrl = string.Format("?ReturnUrl={0}", returnUrl); ???????????string loginUrl = FormsAuthentication.LoginUrl + redirectUrl; ???????????filterContext.HttpContext.Response.Redirect(loginUrl, true); ???????} ???????public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext) { } ???}

2.每个管理后台都少不了权限判断的需求;你可以使用[Authorize(Roles = "r1,r2")] 默认实现进行硬编码,对于用户的权限和角色经常变动的话,或者你需要灵活的处理就需要自定义Authorize,咱们先看下Authorize源代码实现你就会明白


他的实现原理,先判断是否有匿名访问标签,然后利用AuthorizeCore 授权检查,如果未授权利用HandleUnauthorizedRequest 放回401,跳转到登录页面;很明显授权不通过跳转登录页面不是太合适;另一种实现方式自定义Authorize 代码如下:

 ???????public new string[] Roles { get; set; } ???????protected override bool AuthorizeCore(HttpContextBase httpContext) ???????{ ???????????//由原来指定的roles 替换成动态读取的。 ???????????//跟登录用户的roles进行比较。 ???????????if (httpContext == null) ???????????{ ???????????????throw new ArgumentNullException("httpContext"); ???????????} ???????????if (!httpContext.User.Identity.IsAuthenticated) ???????????{ ???????????????return false; ???????????} ???????????if (Roles == null) ???????????{ ???????????????return true; ???????????} ???????????if (Roles.Length == 0) ???????????{ ???????????????return true; ???????????} ???????????if (Roles.Any(new Func<string, bool>(httpContext.User.IsInRole))) ???????????{ ???????????????return true; ???????????} ???????????httpContext.Response.StatusCode = 403; ???????????return false; ???????} ???????protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) ???????{ ???????????filterContext.Result = new HttpUnauthorizedResult(); ???????} ???????public override void OnAuthorization(AuthorizationContext filterContext) ???????{ ???????????bool flag = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true); ???????????if (flag) ???????????{ ???????????????return; ???????????} ???????????string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; ???????????string actionName = filterContext.ActionDescriptor.ActionName; ???????????string roles = string.Join(",", GetRoles(actionName, controllerName)); ???????????if (!string.IsNullOrWhiteSpace(roles)) ???????????{ ???????????????this.Roles = roles.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); ???????????} ???????????base.OnAuthorization(filterContext); ???????????if (filterContext.HttpContext.Response.StatusCode == 403) ???????????{ ???????????????//跳转未授权页面 ???????????????filterContext.Result = new RedirectResult("/Other/Noright"); ???????????} ???????}

3.动作过滤器记录一些ajax的输入输出数据,方便排查问题;代码有注释也比较简单直接贴代码了

 ?public override void OnActionExecuting(ActionExecutingContext filterContext) ???????{ ???????????if (filterContext.HttpContext.Request.IsAjaxRequest()) ???????????{ ???????????????var httpContext = filterContext.HttpContext; ???????????????//输入参数 ???????????????var req = new JavaScriptSerializer().Serialize(HttpContext.Current.Request.Form.AllKeys.ToDictionary(k => k, k => HttpContext.Current.Request.Form[k])); ???????????????var code = httpContext.Request.GetHashCode(); ???????????????var controllerName = filterContext.RouteData.Values["controller"] as string; ???????????????var actionName = filterContext.RouteData.Values["action"] as string; ???????????????var postUrl = controllerName + "/" + actionName; ???????????????LogHelper.WriteDebug( ???????????????????string.Format("RequestUrl:{0};HashCode:{1}</br>RequestParam{2}", ??????????????????postUrl, code, ???????????????????req)); ???????????} ???????} ??????????public override void OnActionExecuted(ActionExecutedContext filterContext) ???????{ ???????????if (filterContext.HttpContext.Request.IsAjaxRequest()) ???????????{ ???????????????//输出参数 ???????????????var jsonR = filterContext.Result as JsonResult; ???????????????var res = new JavaScriptSerializer().Serialize(jsonR); ???????????????LogHelper.WriteDebug(string.Format("OnActionExecuted---返回值:{0}", res)); ???????????} ???????}

4.最后是发生异常的处理,mvc默认实现HandleErrorAttribute,但是也不够灵活,查看源代码


 我们定义之后的代码

 ???public override void OnException(ExceptionContext filterContext) ???????{ ???????????string errCode = ""; ???????????string errMsg = ""; ???????????//自定义错误 ???????????if (filterContext.Exception is ClException) ???????????{ ???????????} ???????????else ???????????{ ???????????????errMsg = "未知错误"; ???????????????LogHelper.WriteError(filterContext.Exception.Message); ???????????} ???????????//如果是ajax请求 ???????????if (filterContext.HttpContext.Request.IsAjaxRequest()) ???????????{ ???????????????var result = new ExceptionResponse ???????????????{ ???????????????????ErrMsg = errMsg, ???????????????}; ???????????????filterContext.Result = new JsonResult() ???????????????{ ???????????????????Data = result ???????????????}; ???????????}//500服务器内部错误 ???????????else ???????????{ ???????????????filterContext.Result = new ViewResult() { ViewName = "/Views/Other/Seerro.cshtml" }; ???????????} ???????????filterContext.ExceptionHandled = true;//阻止golbal里的错误执行 ???????????filterContext.HttpContext.Response.Clear(); ???????????filterContext.HttpContext.Response.StatusCode = 500; ???????????filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;//禁用 IIS 自定义错误 ???????}

 看下弹出的错误效果

mvc的filter

原文地址:http://www.cnblogs.com/chengtian/p/7645022.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved