ASP.NET MVC中Filter过滤器的使用

devtools/2024/12/22 11:02:25/

MVC Filter是典型的AOP(面向切面编程)应用,在ASP.NET MVC中的4个过滤器类型,如下:


但是默认实现它们的过滤器只有三种,分别是ActionFilter(方法),Authorize(授权),HandleError(错误处理)。

  • 特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所应用的元素前面的方括号([ ])来描述的。
  • 特性(Attribute)用于添加元数据,如编译器指令和注释、描述、方法、类等其他信息。.Net 框架提供了两种类型的特性:预定义特性和自定义特性

Filter的默认实现方式就是带有Attribute后缀的,有了Attribute,我们就可以将我们的Filter像标签一样的贴在方法或者控制器的上方

Web Api:   System.Web.Http.Filters.ActionFilterAttribute 继承该类

  • OnActionExecuting  执行前
  • OnActionExecuted   执行后
  • OnResultExecuting  返回前
  • OnResultExecuted   返回后

Mvc:   System.Web.Mvc.ActionFilterAttribute  继承该类

  • OnActionExecuting  执行前  
  • OnActionExecutingAsync  执行前(异步)
  • OnActionExecuted   执行后 
  •  OnActionExecutedAsync   执行后(异步)

1、Action过滤器在ASP.NET MVC中创建MvcApp项目,创建文件夹Filter,然后新建类MyActionFilterAttribute(为了遵循默认的约定,名称以Attribute结尾),继承自ActionFilterAttribute类。ActionFilterAttribute类有如下4个方法。

using System;namespace System.Web.Mvc
{[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);}
}

实现MyActionFilterAttribute类:

using System;
using System.Web.Mvc;namespace MvcApp.Filter
{public class MyActionFilterAttribute : ActionFilterAttribute{public override void OnActionExecuting(ActionExecutingContext filterContext){//1、获取请求的类名和方法名string strController = filterContext.RouteData.Values["controller"].ToString();string strAction = filterContext.RouteData.Values["action"].ToString();//2、用另一种方式获取请求的类名和方法名string strController2 = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;string strAction2 = filterContext.ActionDescriptor.ActionName;filterContext.HttpContext.Response.Write("控制器:" + strController + "<br/>");filterContext.HttpContext.Response.Write("控制器:" + strController2 + "<br/>");filterContext.HttpContext.Response.Write("Action:" + strAction + "<br/>");filterContext.HttpContext.Response.Write("Action:" + strAction2 + "<br/>");filterContext.HttpContext.Response.Write("Action执行前:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");base.OnActionExecuting(filterContext);}public override void OnActionExecuted(ActionExecutedContext filterContext){filterContext.HttpContext.Response.Write("Action执行后:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");base.OnActionExecuted(filterContext);}}
}

对于过滤器,我们可以把它们加在3个地方,一个是控制器上面(控制器下面的所有Action),一个是Action上面(指定标识的Action),另一个就是全局位置(所有控制器中的Action)。这里只演示在Action上面和Home控制器中:

[MyActionFilter]
public ActionResult Index()
{return View();
}

2、Result过滤器

新建MyResultFilterAttribute类,继承ActionFilterAttribute:

using System;
using System.Web.Mvc;namespace MvcApp.Filter
{public class MyResultFilterAttribute : ActionFilterAttribute{/// <summary>/// 加载“视图”前执行/// </summary>/// <param name="filterContext"></param>public override void OnResultExecuting(ResultExecutingContext filterContext){filterContext.HttpContext.Response.Write("加载视图前执行 OnResultExecuting" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");base.OnResultExecuting(filterContext);}/// <summary>/// 加载“视图”后执行/// </summary>/// <param name="filterContext"></param>public override void OnResultExecuted(ResultExecutedContext filterContext){filterContext.HttpContext.Response.Write("加载视图后执行 OnResultExecuted" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");base.OnResultExecuted(filterContext);}}
}

这里把MyResultFilter过滤器加在控制器上面,相当于给Home控制器中的所有的Action方法添加了MyResultFilter过滤器。

using MvcApp.Filter;
using System.Web.Mvc;namespace MvcApp.Controllers
{[MyResultFilter]public class HomeController : Controller{[MyActionFilter]public ActionResult Index(){return View();}}
}

3、AuthorizeAttribute过滤器

创建MyAuthorizeAttribute类,继承AuthorizeAttribute类:

using System.Web.Mvc;namespace MvcApp.Filter
{/// <summary>/// 授权过滤器/// </summary>public class MyAuthorizeAttribute : AuthorizeAttribute{public override void OnAuthorization(AuthorizationContext filterContext){filterContext.HttpContext.Response.Write("OnAuthorization<br/>");//注释掉父类方法,因为父类里的OnAuthorization方法会调用ASP.NET的授权验证机制//base.OnAuthorization(filterContext);}}
}

在控制器Home中的Index上添加MyAuthorize过滤器:

[MyAuthorize]
[MyActionFilter]
public ActionResult Index()
{return View();
}

通常Authorize过滤器也是在全局过滤器上面的,主要用来做登录验证或者权限验证,在App_Start目录下的FilterConfig类的RegisterGlobalFilters方法中添加:

public class FilterConfig
{public static void RegisterGlobalFilters(GlobalFilterCollection filters){//filters.Add(new HandleErrorAttribute());//添加全局授权过滤器filters.Add(new MyAuthorizeAttribute());}
}

在全局中注册过滤器,则所有控制器的所有行为(Action)都会执行这个过滤器。

运行结果,如下图:

4、Exception过滤器

创建MyHandleErrorAttribute类,继承HandleErrorAttribute类:

using System;
using System.Web.Mvc;namespace MvcApp.Filter
{/// <summary>/// 异常处理过滤器/// </summary>public class MyHandleErrorAttribute : HandleErrorAttribute{public override void OnException(ExceptionContext filterContext){ //1、获取异常对象Exception ex = filterContext.Exception;//2、记录异常日志//3、重定向友好页面filterContext.Result = new RedirectResult("~/error.html");//4、标记异常已经处理完毕filterContext.ExceptionHandled = true;base.OnException(filterContext);}}
}

在Action上面添加MyHandleError过滤器:

[MyHandleError]
public ActionResult GetErr()
{int a = 0;int b = 1 / a;return View();
}

创建异常错误友好提示页面error.html。

<body>自定义错误页面
</body>

运行会自动跳转到error.html页面。

如果页面没有跳转,就需要去Web.config配置文件中的<system.web>节点下面添加如下配置节点,开启自定义错误:

<customErrors mode="On"></customErrors>

通常这样的异常处理是放在全局过滤器上面的,只要任意Action方法报错就会执行MyHandleError过滤器中的代码。

修改App_Start目录下面的FilterConfig类:

public class FilterConfig
{public static void RegisterGlobalFilters(GlobalFilterCollection filters){//filters.Add(new HandleErrorAttribute());//添加全局授权过滤器filters.Add(new MyAuthorizeAttribute());//添加全局异常处理过滤器filters.Add(new MyHandleErrorAttribute());}
}

Global.asax下的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;namespace MvcApp
{public class MvcApplication : System.Web.HttpApplication{protected void Application_Start(){AreaRegistration.RegisterAllAreas();FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);}}
}


http://www.ppmy.cn/devtools/2216.html

相关文章

Python零基础从小白打怪升级中~~~~~~~生成器和迭代器

第十七节&#xff1a;生成器和迭代器 一、迭代器 本质&#xff1a; 一个实现了__iter__方法和__next__方法的对象 注意 Iterator对象和 Iterable对象&#xff0c;一个是迭代器&#xff0c;一个是可迭代对象 1、list、dict、str、tuple、set是可迭代对象但不是迭代器&#x…

Kafka 知识汇总学习

kafka:消息发布队列、具有存储的功能 生产者 消费者 优势&#xff1a;吞吐量高&#xff0c;性能好&#xff1b; 具有良好的伸缩性&#xff0c;支持在线水平扩展; 具有容错性和可靠性&#xff1b; 与大数据生态结合 Kafka 是一个分布式系统&#xff0c;由服务器和客户端组成&…

新型物联网创新实践教学体系建设

新型物联网创新实践教学体系建设 一、设计背景 随着物联网技术的快速发展&#xff0c;物联网已成为当今科技创新的重要领域。为了培养能够紧跟物联网技术发展趋势的高素质人才&#xff0c;高校物联网专业教学急需构建一套创新实践教学体系。本毕业设计旨在探索和设计一套新型…

社交创新的标杆:解读Facebook的社交模式

引言 在当今数字化时代&#xff0c;社交媒体已成为人们日常生活和沟通的重要工具。作为全球最大的社交媒体平台&#xff0c;Facebook不仅改变了我们的社交模式&#xff0c;而且对全球的社交文化、商业活动和公共事务产生了深远的影响。本文将深入探讨Facebook的社交模式&#…

yolov8目标检测 部署瑞芯微rk3588记录

1. 前置条件 本地电脑系统&#xff0c;ubuntu20.04 训练代码&#xff1a; 训练代码下载的ultralytics官方代码 SHA&#xff1a;6a2fddfb46aea45dd26cb060157d22cf14cd8c64 训练代码仅做数据修改&#xff0c;类别修改&#xff0c;代码结构未做任何修改 需要准备的代码&#…

视频批量高效剪辑,支持将视频文件转换为音频文件,轻松掌握视频格式

在数字化时代&#xff0c;视频内容日益丰富&#xff0c;管理和编辑这些视频变得愈发重要。然而&#xff0c;传统的视频剪辑软件往往操作复杂&#xff0c;难以满足高效批量处理的需求。现在&#xff0c;一款全新的视频批量剪辑神器应运而生&#xff0c;它支持将视频文件一键转换…

怎么使用JMeter进行性能测试?

一、简介 JMeter是Apache软件基金会下的一款开源的性能测试工具&#xff0c;完全由Java开发。它专注于对我们应用程序进行负载测试和性能测量&#xff0c;最初设计用于web应用程序&#xff0c;现在已经扩展到其他测试功能&#xff0c;比如&#xff1a;FTP、Database和LDAP等。…

如何用Redis高效实现12306的复杂售票业务

12306的售票业务是一个复杂的系统&#xff0c;需要考虑高并发、高可用、数据一致性等问题。使用Redis作为缓存和持久化存储&#xff0c;可以提高系统的性能和可扩展性&#xff0c;以下是一些可能的实现方式&#xff1a; 1 票源信息缓存&#xff1a;将票源信息&#xff08;如车次…