1、方案一:ActionFilterAttribute
1.1、自定义一个类,以Attribute结尾,继承ActionFilterAttribute抽象类,重写抽象类的虚方法(引入using System.Web.Mvc)
namespace Filter.Filter
{
public class CustomFilter:ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)//在方法执行后
{
base.OnActionExecuted(filterContext);
}
public override void OnActionExecuting(ActionExecutingContext filterContext)//在方法执行前
{
base.OnActionExecuting(filterContext);
}
public override void OnResultExecuted(ResultExecutedContext filterContext)//返回视图后
{
base.OnResultExecuted(filterContext);
}
public override void OnResultExecuting(ResultExecutingContext filterContext)//在返回视图前
{
base.OnResultExecuting(filterContext);
}
}
}
1.2、在需要执行过滤器的方法上,标记自定义的实现类(引入自定义类所在的命名空间)
[CustomFilter]//标记自定义的过滤器
public ActionResult Index()
{
return View();
}
2、方案二IActionFilter
2.1 自定义一个类,以Attribute结尾,继承抽象类FilterAttribute,IActionFilter(引入using System.Web.Mvc)
namespace Filter.Filter
{
public class CustomIActionFilterAttribute:FilterAttribute,IActionFilter
{
//需要标记public
public void OnActionExecuted(ActionExecutedContext filterContext) {
}
//需要标记public
public void OnActionExecuting(ActionExecutingContext filterContext) {
}
}
}
2.2、在需要执行过滤器的方法上,标记自定义的实现类(引入自定义类所在的命名空间)。
[CustomIActionFilterAttribute]
public ActionResult Index()
{
return View();
}
3、IActionFilter的应用+多种注册
3.1、数据压缩
namespace Filter.Filter
{
public class CustomIActionFilterAttribute:FilterAttribute,IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext) {
}
public void OnActionExecuting(ActionExecutingContext filterContext) {
var request = filterContext.HttpContext.Request;
var respose = filterContext.HttpContext.Response;
//request.Headers是NameValueCollection类型(map类型,该类在一个键下存储多个字符串值)
//获取浏览器支持的压缩格式
string acceptEncoding = request.Headers["Accept-Encoding"];
//判断是否支持zgip压缩
if (!string.IsNullOrEmpty(acceptEncoding) && acceptEncoding.ToUpper().Contains("GZIP")) {
//告诉浏览器后台压缩的格式
respose.AddHeader("Content-Encoding", "gzip");
//设置后台的压缩格式
respose.Filter = new GZipStream(respose.Filter, CompressionMode.Compress);
}
}
}
}
3.2、多种注册方式(标记在controller)
自定义过滤器实现类,标记在controller,controller下的所有方法都生效
3.3、多种注册方式(全局注册)
在App_Start目录下的FilterConfig.cs 中进行添加
namespace Filter
{
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new CustomIActionFilterAttribute());
}
}
}
4、结果过滤器
4.1、自定义实现类以Attribute结尾,继承FilterAttribute, IResultFilter
public class CustomResultNewFilterAttribute : FilterAttribute, IResultFilter
{
public void OnResultExecuting(ResultExecutingContext filterContext)
{
}
public void OnResultExecuted(ResultExecutedContext filterContext)
{
}
}
5、异常处理过滤器(异常处理器,一般需要全局注册)
5.1、方案一 :HandleErrorAttribute
//自定义实现类,以Attribute结尾,继承HandleErrorAttribute
public class CustomHandleErrorAttribute: HandleErrorAttribute
{
/// <summary>
/// 如果有异常发生,就跳转到这儿来
/// </summary>
/// <param name="filterContext"></param>
public override void OnException(ExceptionContext filterContext)
{
if (!filterContext.ExceptionHandled)
{
//就处理异常
//1.如果是访问页面,----应该展示一个页面出去--报错异常信息
//2.如果是Ajax请求---就应该响应一个JSON格式的数据出去
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new JsonResult()
{
Data = new
{
DebugMessage = filterContext.Exception.Message,
RetValue = "",
PromptMsg = "发生错误,请联系管理员"
}
};
}
else
{
filterContext.Result = new ViewResult()//短路器
{
ViewName = "~/Views/Shared/Error.cshtml",
ViewData = new ViewDataDictionary<string>(filterContext.Exception.Message)
};
}
filterContext.ExceptionHandled = true;//已经被我处理了
}
}
}
5.2、方案二:自定义实现类,以Attribute结尾,继承:FilterAttribute,IExceptionFilter
public class CustomExceptionFilterAttribute :FilterAttribute,IExceptionFilter
{
/// <summary>
/// 当有异常的时候,触发这里
/// </summary>
/// <param name="filterContext"></param>
public void OnException(ExceptionContext filterContext)
{
if (!filterContext.ExceptionHandled)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new JsonResult()
{
Data = new
{
DebugMessage = filterContext.Exception.Message,
RetValue = "",
PromptMsg = "发生错误,请联系管理员"
}
};
}
else
{
filterContext.Result = new ViewResult()//短路器
{
ViewName = "~/Views/Shared/Error.cshtml",
ViewData = new ViewDataDictionary<string>(filterContext.Exception.Message)
};
}
filterContext.ExceptionHandled = true;//已经被我处理了
}
}
}
5.3、上面的两种异常处理方式,并不能捕获所有的异常情况,为了能够捕获所有的异常情况,需要在global.asax中添加一些代码作为补充(上面两种方案和这个补充方法联合使用)
///只要是响应不是200,就能被这里捕捉到;可以捕捉到异常的漏网之鱼;
protected void Application_Error(object sender, EventArgs e)
{
Exception excetion = Server.GetLastError();
Response.Write("出现错误请联系管理员....");
Server.ClearError();
}