(精华)2020年8月20日 ASP.NET MVC Attribute特性的使用(行为,异常,权限)

Authorize权限认证

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true)]
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    private Logger logger = new Logger(typeof(CustomAuthorizeAttribute));
    private string _LoginUrl = null;
    public CustomAuthorizeAttribute(string loginUrl = "~/Sixth/Login")
    {
        this._LoginUrl = loginUrl;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var httpContext = filterContext.HttpContext;//能拿到httpcontext 就可以为所欲为 

        if (filterContext.ActionDescriptor.IsDefined(typeof(CustomAllowAnonymousAttribute), true))
        {
            return;
        }
        else if (filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(CustomAllowAnonymousAttribute), true))
        {
            return;
        }
        //var memberValidation = HttpContext.Current.Request.Cookies.Get("CurrentUser");//使用cookie
        //也可以使用数据库、nosql等介质
        else if (httpContext.Session["CurrentUser"] == null
             || !(httpContext.Session["CurrentUser"] is CurrentUser))//为空了,
        {
            if (httpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new NewtonJsonResult(new AjaxResult()
                {
                    Result = DoResult.OverTime,
                    DebugMessage = "需要登录",
                    RetValue = ""
                });

            }
            else
            {
                //就标识没有权限
                httpContext.Session["CurrentUrl"] = httpContext.Request.Url.AbsoluteUri;
                filterContext.Result = new RedirectResult(this._LoginUrl);
            }
        }
        else
        {
            {
                CurrentUser current = (CurrentUser)httpContext.Session["CurrentUser"];
                //你是什么角色,可以访问那些页面? 
                //可以在这里加一下逻辑校验;
                {
                    //可以连接数据库去做检验;
                } 
                //如果把Filter写到 Advanced.Framework;MVC,需要引用Advanced.Framework;
                //数据库访问层也需要引用Advanced.Framework 
                //但是这里也需要连接数据库做数据校验;
                //就会循环引用;
                //可以通过传递委托来解决;
            }
            CurrentUser user = (CurrentUser)httpContext.Session["CurrentUser"];
            //this.logger.Info($"{user.Name}登陆了系统");
            return;//继续
        }
        //base.OnAuthorization(filterContext);
    }
}
public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        //filters.Add(new CustomAuthorizeAttribute("~/XT/Login"));
    }
}
public class CustomAllowAnonymousAttribute : Attribute
{
}

HandleError异常处理

[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public class LogExceptionFilter : HandleErrorAttribute
{
    private Logger logger = Logger.CreateLogger(typeof(LogExceptionFilter));
    public override void OnException(ExceptionContext filterContext)
    {
        if (!filterContext.ExceptionHandled)//异常有没有被处理过
        {
            string controllerName = (string)filterContext.RouteData.Values["controller"];
            string actionName = (string)filterContext.RouteData.Values["action"];
            string msgTemplate = "在执行 controller[{0}] 的 action[{1}] 时产生异常";
            logger.Error(string.Format(msgTemplate, controllerName, actionName), filterContext.Exception);

            if (filterContext.HttpContext.Request.IsAjaxRequest())//检查请求头 是不是XMLHttpRequest
            {
                filterContext.Result = new JsonResult()
                {
                    Data = new AjaxResult()
                    {
                        Result = DoResult.Failed,
                        PromptMsg = "系统出现异常,请联系管理员",
                        DebugMessage = filterContext.Exception.Message
                    }//这个就是返回的结果
                };
            }
            else
            {
                filterContext.Result = new ViewResult()
                {
                    ViewName = "~/Views/Shared/Error.cshtml",
                    ViewData = new ViewDataDictionary<string>(filterContext.Exception.Message)
                };
            }
            filterContext.ExceptionHandled = true;
        }
    }
}
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    //filters.Add(new HandleErrorAttribute());
    filters.Add(new CustomHandleErrorAttribute());//全部的控制器全部的action都生效
}

捕获异常情况表

//1 Action异常,没被catch T
//2 Action异常,被catch F
//3 Action调用Service异常 T 异常冒泡
//4 Action正常视图出现异常 T ExecuteResult是包裹在try里面的
//5 控制器构造出现异常 F 控制器构造后才有Filter
//6 Action名称错误 F 因为请求其实都没进mvc流程
//7 任意错误地址 F
//8 权限Filter异常 T 权限fileter也是在try里面的

需要异常全部捕获还需要在全局文件添加

/// <summary>
/// 全局式的异常处理,可以抓住漏网之鱼
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Application_Error(object sender, EventArgs e)
{
    Exception excetion = Server.GetLastError();
    this.logger.Error($"{base.Context.Request.Url.AbsoluteUri}出现异常");
    Response.Write("System is Error....");
    Server.ClearError();

    //Response.Redirect
    //base.Context.RewritePath("/Home/Error?msg=")
}

Action行为过滤

public class CustomActionFilterAttribute : ActionFilterAttribute
{
    Logger Logger = new Logger(typeof(CustomActionFilterAttribute));

    private static Dictionary<string, List<LimtInfo>> limitcountDictionary = new Dictionary<string, List<LimtInfo>>();

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        this.Logger.Info($"请求{filterContext.RouteData.Values["action"]},参数为:{Newtonsoft.Json.JsonConvert.SerializeObject(filterContext.ActionParameters)}");

        //#region 参数校验
        var parrameter = filterContext.ActionParameters;
        if (true) //如果这个参数不满足什么要求
        { 
            filterContext.Result=
        } 
        通过去除Session,和数据做校验;
        //#endregion

        //#region 缓存
        Key:filterContext
        filterContext.HttpContext.Request.Url.AbsoluteUri;
        //#endregion 
        //#region 限流
        //string absoluteUri = filterContext.HttpContext.Request.Url.AbsoluteUri;
        //if (limitcountDictionary.Keys.Contains(absoluteUri))
        //{
        //    //从10秒钟之前到现在这一刻中间请求了多少次;
        //   int limitCout=  limitcountDictionary[absoluteUri].Where(l => l.RequestTime > DateTime.Now.AddSeconds(-10)).Count();
        //    if (limitCout>50)
        //    {
        //        //跳转到错误页面
        //    }
        //    //继续 
        //} 
        //#endregion

        this.Logger.Info($"CustomActionFilterAttribute.OnActionExecuting");
        //base.OnActionExecuting(filterContext);
    }


    public override void OnActionExecuted(ActionExecutedContext filterContext)
    { 
        this.Logger.Info($"请求{filterContext.RouteData.Values["action"]} 结束,执行结果为:{Newtonsoft.Json.JsonConvert.SerializeObject(filterContext.Result)}");

        this.Logger.Info($"CustomActionFilterAttribute.OnActionExecuted");
        base.OnActionExecuted(filterContext); 
        //#region 限流 
        //limitcountDictionary[filterContext.HttpContext.Request.Url.AbsoluteUri].Add(new LimtInfo()
        //{
        //    RequestTime = DateTime.Now
        //}) ; 
        //#endregion
    }


    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        this.Logger.Info($"CustomActionFilterAttribute.OnResultExecuting");
        //base.OnResultExecuting(filterContext);
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        this.Logger.Info($"CustomActionFilterAttribute.OnResultExecuted");
        //base.OnResultExecuted(filterContext);
    }
}
public class CompressActionFilterAttribute: ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var request = filterContext.HttpContext.Request;
        var response = filterContext.HttpContext.Response;
        string acceptencoding=request.Headers["accept-encoding"];
        if (!string.IsNullOrWhiteSpace(acceptencoding)  && acceptencoding.ToUpper().Contains("GZIP")) //表示支持GZIP压缩
        {
            response.AddHeader("Content-Encoding","gzip"); //服务器告诉客户端,我这里已经使用的是gzip格式压缩;
            response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);//返回的结果进行压缩
        }


        //base.OnActionExecuting(filterContext);
    }
}

public class LimtInfo
{
    public DateTime RequestTime { get; set; } 
}


public class CustomActionActionFilterAttribute : FilterAttribute, IActionFilter
{
    Logger Logger = new Logger(typeof(CustomActionFilterAttribute));

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        throw new NotImplementedException();
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        throw new NotImplementedException();
    }
}

public class CustomResultFilterAttribute : FilterAttribute, IResultFilter
{
    Logger Logger = new Logger(typeof(CustomActionFilterAttribute));

    public void OnResultExecuted(ResultExecutedContext filterContext)
    {
        throw new NotImplementedException();
    }

    public void OnResultExecuting(ResultExecutingContext filterContext)
    {
        throw new NotImplementedException();
    }
}

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new CustomActionFilterAttribute());
    }
}

配置方式创建特性

<appSettings>
  <add key="filterConfig" value="Advacned.MVC.Filters,Advacned.MVC.Filters.ActionFilterAttribute" />
</appSettings>

程序集外

public class ctionFilterAttribute: ActionFilterAttribute
{
    Logger Logger =  Logger.CreateLogger(typeof(RichardActionFilterAttribute));
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Logger.Info("这是Action执行完毕了。。。");

        base.OnActionExecuted(filterContext);
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Logger.Info("这是Action执行之前");

        base.OnActionExecuting(filterContext);
    }
}
public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(SimpFactory.CreateFilter());
    }
}
©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师:上身试试 返回首页