欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

asp.net mvc 过滤器

程序员文章站 2022-09-07 21:02:36
业务场景 在实际操作中,经常需要将用户的操作记录到日志中,或者是验证用户是否登录了网站,面对这样的需求,以前的操作是自定义一个统一的全局方法,然后做处理,在每个需要的页面中添加想要的函数调用,这导致了多个页面中存在了大量重复的代码,这样的方式不太符合软件工程的思想。为了解决这个问题,mvc为我们提供 ......

 

业务场景

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

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

  1. iactionfilter(方法过滤器):接口名为[iactionfilter],在控制器方法调用前/后执行
  2. iresultfilter(结果过滤器):接口名为[iresultfilter],在控制器方法调用完,跳转至view页面前/后执行
  3. iauthorizationfilter(授权过滤器):接口名为[iauthorizationfilter],所有过滤器中最先执行的
  4. iexceptionfilter(异常处理过滤器):接口名为[iexceptionfilter],在控制器方法抛出异常时执行

根据这里的执行顺序,我们可以在不同的需求下自行实现对应的控制器,

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

这里我们可以通过继承filterattribute类来实现。

代码场景

按照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]

    public class homecontroller : controller
    {
        [helpclassattribute]
        public actionresult index()
        {
            return view();
        }
    }

点击调试:

asp.net mvc 过滤器

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

我们可以根据实际的逻辑去重写自己的过滤器。

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

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的方式运行,结果如下:

asp.net mvc 过滤器

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

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

asp.net mvc 过滤器

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

asp.net mvc 过滤器

 

 

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

当然对于异常处理过滤器来说,我在每个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]特性,然后发布,调试结果:结果一样

asp.net mvc 过滤器

 

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

 

 

 

 

原文链接:

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