asp.net mvc 过滤器

 

业务场景

        在实际操做中,常常须要将用户的操做记录到日志中,或者是验证用户是否登陆了网站,面对这样的需求,之前的操做是自定义一个统一的全局方法,而后作处理,在每一个须要的页面中添加想要的函数调用,这致使了多个页面中存在了大量重复的代码,这样的方式不太符合软件工程的思想。为了解决这个问题,mvc为咱们提供了过滤器来完成对应的功能,经过过滤器,咱们只须要将相应的业务处理代码写一次,再在相应的功能处经过特性的方式来使用写好的过滤器。一句话,咱们能够用过滤器来分离与业务逻辑无关却常常须要执行的代码,既保证业务逻辑的正确性,也保证了代码的简洁直观。html

那咱们可使用哪些过滤器呢,这里一共有四种过滤器,解释以下mvc

  1. IActionFilter(方法过滤器):接口名为[IActionFilter],在控制器方法调用前/后执行
  2. IResultFilter(结果过滤器):接口名为[IResultFilter],在控制器方法调用完,跳转至view页面前/后执行
  3. IAuthorizationFilter(受权过滤器):接口名为[IauthorizationFilter],全部过滤器中最早执行的
  4. IExceptionFilter(异常处理过滤器):接口名为[IExceptionFilter],在控制器方法抛出异常时执行

根据这里的执行顺序,咱们能够在不一样的需求下自行实现对应的控制器,ide

须要注意的是,除了咱们须要实现对应的过滤器接口外,同时还须要保证对应的过滤器是特性类,函数

这里咱们能够经过继承FilterAttribute类来实现。post

代码场景

按照MVC约定的方式来命名,过滤器以Attribute来结尾。网站

 public class HelpClassAttribute : FilterAttribute, IActionFilter 
    {
        //     在执行操做方法后调用。
        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            
        }
        //     在执行操做方法以前调用。
        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.Result = new System.Web.Mvc.ContentResult() { Content = "在执行操做方法以前调用。" };
            return;
        } 
    }

而后在HomeController中添加添加特性[HelpClassAttribute]spa

    public class HomeController : Controller
    {
        [HelpClassAttribute]
        public ActionResult Index()
        {
            return View();
        }
    }

点击调试:3d

这样子,一个简单的过滤器就实现了。调试

咱们能够根据实际的逻辑去重写本身的过滤器。日志

另一个比较经常使用的是异常过滤器

1,新建SystemErrorAttribute.cs

须要注意,这里继承的是:System.Web.Mvc.HandleErrorAttribute

public class SystemErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        base.OnException(filterContext);
        //处理错误消息,将其跳转到一个页面
        string controllerName = (string)filterContext.RouteData.Values["controller"];
        string actionName = (string)filterContext.RouteData.Values["action"];
        //这里简单向C盘的test.log写入了文件
        FileStream fs = new FileStream(@"C:\test.log", FileMode.OpenOrCreate, FileAccess.Write);
        StreamWriter sw = new StreamWriter(fs);
        sw.BaseStream.Seek(0, SeekOrigin.End);
        string writeText = string.Format("controllerName:[{0}]actionName:[{1}]{2}",
            controllerName, actionName, filterContext.Exception.ToString());
        sw.WriteLine(writeText);
        sw.Flush();
        sw.Close();
        fs.Close();

        /*//这里是使用log4net来记录
        log4net.ILog log = log4net.LogManager.GetLogger("controllerName:[" + controllerName + "]actionName:[" + actionName+"]");
        log.Error(filterContext.Exception.ToString());
        */

        //錯誤友好輸出,这里从新构造了一个ActionResult
        filterContext.Result = new System.Web.Mvc.ContentResult() { Content = "系统错误,请联系管理员" };
        return;
    }
}

2,在HomeController中添加MyError()

public class HomeController : Controller
{
    [Filters.SystemError]//添加
    public ActionResult MyError()
    {
        //人为制造一个错误
        int a = 1;
        int b = 0;
        return Content((a/b).ToString());
    }
}

3,调试:注意:这里须要采用Ctrl+F5的方式运行,结果以下:

到这里,可能会有很大疑问,为何没有产生友好提示呢?在过滤器中不是明明有添加友好提示吗?

先看一下C盘的日志:test.log

日志有成功产生。没有出现友好提示的缘由在于不是正式的环境,VS为了方便调试,不会隐藏错误信息。下面将应用部署到真实的环境中去调试,看结果:

 

 

这下友好提示又出来了。。。

固然对于异常处理过滤器来讲,我在每一个Action都来添加特性,仍是很麻烦,这里咱们就要注册成为全局过滤器:

①,打开App_Start文件夹中的FilterConfig.cs

添加:filters.Add(new Filters.SystemErrorAttribute());

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        //添加这个
        filters.Add(new Filters.SystemErrorAttribute());

        filters.Add(new HandleErrorAttribute());
    }
}

②,在HomeController去掉[Filters.SystemError]特性,而后发布,调试结果:结果同样

 

就这样,全局异常处理就完成了。

 

 

 

 

原文连接:https://www.cnblogs.com/ives/p/filter.html

                  https://www.cnblogs.com/chuliam/p/studyFilter.html

相关文章
相关标签/搜索