AOP权限认证、异常处理、日志记录

AOP基础:参考文章

文章基于MVC框架。

1.MVC路由小知识

在RouteConfig类中新建一个类,重写GetRouteData方法,进行一些类似于浏览器监察,判断是否用的是相应版本的浏览器或者哪种浏览器等。

 public class MyRoute : RouteBase
    {
        public override RouteData GetRouteData(HttpContextBase httpContext)
        {
            if (httpContext.Request.UserAgent.Contains("Chrome"))
            {
                return null;
            }
            else
            {
                RouteData routeData = new RouteData(this, new MvcRouteHandler());
                routeData.Values.Add("controller", "Home");
                routeData.Values.Add("action", "Refuse");
                return routeData;
            }
        }

        public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
        {
            throw new NotImplementedException();
        }
    }

在RegisterRoutes中添加浏览器验证:

routes.Add("browser",new MyRoute());

2.权限验证

新建一个特性类,重写AuthorizeAttribute中的OnAuthorization方法

public class CustomAuthorizeAttribute:AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            //base.OnAuthorization(filterContext);
            //Console.WriteLine(filterContext.HttpContext.Request.Url.AbsoluteUri);
            //return;

            var user = filterContext.HttpContext.Session["CurrentUser"];

            if(filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute),true))
            {
                return;
            }
            else if(filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute),true))
            {
                return;
            }
            else if(user==null||string.IsNullOrEmpty(user.ToString()))
            {
                filterContext.Result = new RedirectResult("~/Second/Login");
            }
            else
            {
                return;
            }
        }
    }

在Global.asax中

 protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();//注册区域
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);//Filter 全局验证
            RouteConfig.RegisterRoutes(RouteTable.Routes);//注册路由
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);//Filter 全局验证

F12进入到FilterConfig中添加全局验证,

 filters.Add(new CustomAuthorizeAttribute());

但是这样添加上之后就会使所有的页面,所有的Action都会有验证,对于一些Action或者页面避免验证:就要在相应的位置添加特性AllowAnonymousAttribute。

2.异常处理

添加异常特性类CustomHandleErrorAttribute

public class CustomHandleErrorAttribute:HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            //base.OnException(filterContext);
            //Console.WriteLine(filterContext.HttpContext.Request.Url.AbsoluteUri);
            //Console.WriteLine(filterContext.Exception.Message);
            if(!filterContext.ExceptionHandled)//表示未被别的Filter处理
            {
                //跳转到错误页
                //filterContext.Result = new RedirectResult("~/Second/Login");
                filterContext.Result = new ViewResult()
                {
                    ViewName = "~/Views/Shared/Error.cshtml",
                    ViewData = new ViewDataDictionary<string>(filterContext.Exception.Message)
                };
                filterContext.ExceptionHandled = true;
            }
        }
    }

同样在FilterConfig中添加全局Filter,

filters.Add(new CustomHandleErrorAttribute());

这样一般的异常都会跳转到错误页面。

但对于一些4XX错误类的异常无法捕获,如果需要这样的处理可以在Global.asax中添加一个全局异常处理:

 /// <summary>
        /// 全局异常处理,
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Application_Error(object sender,EventArgs e)
        {
            var ex = Server.GetLastError();
            Response.Clear();
            Response.Write("This is Error by Global!");
            Response.ContentType = "text/html";
            Response.End();
        }

3.日志记录

新建CustomActionFilterAttribute特性类,继承ActionFilterAttribute

  /// <summary>
        /// Action 执行前完成 可以检查参数
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            
            string record = $"记录事件操作:";
            foreach (var value in filterContext.RouteData.Values)
            {
                record += $"{value.Key}:{value.Value}";
            }
            record += $"执行开始,操作人:{filterContext.HttpContext.Session["CurrentUser"]},操作时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}。\r\n";
            filterContext.HttpContext.Response.Write(record);
           
        }
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {

            filterContext.HttpContext.Response.Write($"This is {nameof(CustomActionFilterAttribute)} {nameof(OnActionExecuted)}");//
            //检测浏览器支持的压缩格式
            //var request = filterContext.HttpContext.Request;
            //var response = filterContext.HttpContext.Response;
            //string encoding = request.Headers["Accept-Encoding"];
            //if(!string.IsNullOrEmpty(encoding))
            //{
            //    if(encoding.ToLower().Contains("gzip"))
            //    {
            //        //要求服务器压缩
            //        response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
            //        response.AppendHeader("Contend-encoding", "gzip");
            //    }
            //}
            base.OnActionExecuted(filterContext);
        }
        /// <summary>
        /// 在ExecuteResult之前
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            base.OnResultExecuting(filterContext);
        }
        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            base.OnResultExecuted(filterContext);
        }

这里没有提供日志的记录具体方法,只提供特性类,只要在里面调用记录日志的方法就可以记录没步骤的操作,操作人,操作时间。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨中深巷的油纸伞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值