栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

MVC 扩展FilterAttribute

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MVC 扩展FilterAttribute

MVC的行为过滤器特性(FilterAttribute)扩展
    扩展ActionFilterAttribute扩展IActionFilter
扩展ActionFilterAttribute

其内部依然是实现了IActionFilter的接口,并以虚函数可重写的形式进行.如下:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
    {
     
        protected ActionFilterAttribute();

        
        public virtual void OnActionExecuted(ActionExecutedContext filterContext);
       
        public virtual void OnActionExecuting(ActionExecutingContext filterContext);
       
        public virtual void OnResultExecuted(ResultExecutedContext filterContext);
        
        public virtual void OnResultExecuting(ResultExecutingContext filterContext);
    }

该基类ActionFilterAttribute实现了IActionFilter和IResultFilter两个接口.
如下:

public interface IActionFilter
{
   
    void OnActionExecuted(ActionExecutedContext filterContext);
    
    void OnActionExecuting(ActionExecutingContext filterContext);
}

public interface IResultFilter
 {
 
     void OnResultExecuted(ResultExecutedContext filterContext);
    
     void OnResultExecuting(ResultExecutingContext filterContext);
 }


两个接口中的函数

Action 在执行控制器方法中和方法后进行调用.Result在渲染前端视图中和选然后调用.

public class CustomActionFilterAttribute:ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            cw($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}OnActionExecuted");
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            cw($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}OnActionExecuting");
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            cw($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}OnResultExecuted");
        }

        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            cw($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}OnResultExecuting");
        }
    }

运行过程中顺序是:OnActionExecuting->执行控制器->OnActionExecuted->OnResultExecuting->渲染视图->OnResultExecuted

IActionFilter和IResultFilter

其实上述的两个Attribute都是实现了这两个接口,由于是特性,所以仅仅继承Attribute是无效的.

无效

public class CustomActionFilterAttribute2 : Attribute, IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            cw($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}OnActionExecuted");
        }

        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            cw($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}OnActionExecuting");
        }
    }

其原因在于这里Attribute是继承自FilterAttribute,又实现了IMvcFilter接口.

能干啥?

日志记录,任何一个位置都会有不可预料的错误发生.最重要的是,浏览器和服务器在进行请求响应操作时,是需要一定的数据传送的.传送的长短就会直观反映到响应的速度上.

在需要关注点的位置上进行编写.
数据压缩上,那就是在执行OnActionExecuting时要做的.

public void OnActionExecuting(ActionExecutingContext filterContext)
{
     //获取浏览器和服务器同时支持的压缩规则.
     var request=filterContext.HttpContext.Request;
     var response=filterContext.HttpContext.Response;
     //获取浏览器支持的压缩格式.
	string accept_ecode=request.Headers["Accept-Encoding"];
	if(!string.IsNullOrWhiteSpace(accept_ecode)&&accept_ecode.ToUpper().Contains("GZIP")){
		response.AddHeader("Content-Encoding","gzip");//设置服务器响应头解压方式.
		response.Filter=new GZipStream(response.Filter,CompressionMode.Compress);//压缩类型指定.

	//日志记录.log4net
	            myLogger.Info($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}OnActionExecuting");

	}
}
属性的注册方式
    全局注册(在App_Start/FilterConfig.cs进行)
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            //filters.Add(new HandleErrorAttribute());
            //整个项目都将应用.
            filters.Add(new CustomActionFilterAttribute());
        }
    
    标记在控制器上(所有Action都将应用)
    [CustomActionFilterAttribute]
    public class CustomController{}
    
    标记在Action上.只对此action生效.
ExceptionFilter

异常Filter
常规操作:try-catch包裹,代码冗余.

    HandlerErrorAttributeIExceptionFilter
HandleErrorAttribute扩展

重写或实现

public virtual void OnException(ExceptionContext filterContext){
	if(!filterContext.ExceptionHandler){
		//处理异常.
		//1.如果是访问页面,展示一个页面出去,报出异常消息.
		//2.ajax请求,响应一个json格式的数据出去.
		if(filterContext.HttpContext.Request.IsAjaxRequest()){//是否为Ajax请求.
		filterContext.Result=new JsonResult(){
			Data=new{
				DebugMessage=filterContext.Exception.Message,
				RetValue="",
				promptMsg="发生错误,请联系管理员"
			}
		};
	}
	else{
		filterContext.Result=new ViewResult(){
			ViewName="",//指定错误页面.
			ViewData=new ViewDataDictionary(filterContext.Exception.Message)//错误消息.
		};
	}
	filterContext.ExceptionHandler=true;
}

但依然会存在异常捕捉不到的,上面的更偏向于业务异常方面.若访问一个不该访问的页面,上述方法页无能为力了.

需要在Global.asax(全局处理)中进行

///响应!=200,被这里捕捉.
protected void App_err(object s,EventArgs e){
	Exception ex=Server.GetLastError();//获取最后的响应错误.
	Response.Write();//返回一个错误页面.
	Server.ClearError();
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/755751.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号