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

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.hqwc.cn/news/641540.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rust-01 Hello Rust 10分钟上手编写第一个Rust程序 背景介绍 发展历史 环境配置 升级打怪的必经之路

背景介绍 Rust 是一种多范式、通用的编程语言&#xff0c;强调性能、类型安全和并发性。它通过一个称为“借用检查器”的机制在编译时追踪所有引用的对象生命周期&#xff0c;以强制实现内存安全&#xff0c;即确保所有引用都指向有效的内存&#xff0c;而不需要垃圾收集器。 …

小程序中使用HTTPS调用自带文本安全内容检测接口(msg_sec_check)的实现方法

在小程序中调用自带的文本安全内容检测接口&#xff0c;你需要使用小程序提供的wx.request方法。以下是一个示例代码&#xff1a; javascript代码: // 假设你已经获取了access_token,如果不知道如何获取&#xff0c;可以参考我上一篇文章 const access_token 你的access_tok…

JS 删除数组元素( 5种方法 )

No.内容链接1Openlayers 【入门教程】 - 【源代码示例300】 2Leaflet 【入门教程】 - 【源代码图文示例 150】 3Cesium 【入门教程】 - 【源代码图文示例200】 4MapboxGL【入门教程】 - 【源代码图文示例150】 5前端就业宝典 【面试题详细答案 1000】 文章目录 一、五种…

QT中文乱码常见解决办法

QT中出现中文字符串乱码情况时(如图示), 可尝试下面的几种方法: 1、QString str QStringLiteral("1你好世界 hello world")); //推荐2、QString str QObject::tr("2你好世界 hello world")); //推荐国际化场景使用3、QString str QString::fromU…

Linux内核驱动开发-001字符设备开发-003独立按键杂项驱动

1驱动程序 /*************************************************************************> File Name: key_misc.c> Author: yas> Mail: rage_yashotmail.com> Created Time: 2024年04月22日 星期一 17时20分42秒**********************************************…

DBA-现在应该刚刚入门吧

说来话长 在2023年以前&#xff0c;我的DBA生涯都是“孤独的”。成长路径除了毕业前的实习期有人带&#xff0c;后续几乎都是靠自学。如何自学&#xff0c;看视频、看文档、网上查阅资料、项目实战。 可能是学疏才浅 &#xff0c;一直都是在中小公司混&#xff0c;在中小公司通…

30V-STM32设计项目

30V-STM32设计 一、项目描述 (已验证) 基于STM32c8t6芯片设计的开发板&#xff0c;支持4-30V宽电压输入&#xff0c;串口模式自动下载功能&#xff0c;支持串口和STlink&#xff0c;方式下载程序 二、原理图介绍 电源电路采用了DCDCLDO电路&#xff0c;如果是外接DC头供电的话&…

GELU激活函数

Gaussian Error Linerar Units(GELUS) 论文链接&#xff1a;https://arxiv.org/abs/1606.08415 在激活函数领域&#xff0c;鄙视链应该是&#xff1a;Elus > Relu > Sigmoid &#xff0c;这些激活函数都有自身的缺陷&#xff0c; sigmoid容易饱和&#xff0c;Elus与Rel…

【Transformer】detr之encoder逐行梳理(二)

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 detr之encoder逐行梳理 1. 整体 encoder由encoder layer构成 输入进encoder的特征shape:(hw,b,c)&#xff0c;后文将给出说明 class Transformer(nn.…

java-springmvc 01

MVC就是和Tomcat有关。 01.MVC启动的第一步&#xff0c;启动Tomcat 02.Tomcat会解析web-inf的web.xml文件

《架构风清扬-Java面试系列第23讲》如何理解Java的泛型檫除?

晚上好&#xff0c;给大家加个餐 来&#xff0c;思考片刻&#xff0c;说出你的答案 1&#xff0c;什么是泛型檫除&#xff1f; 泛型擦除是指编译器在处理泛型代码时&#xff0c;会在编译阶段移除&#xff08;擦除&#xff09;所有与泛型相关的类型参数信息&#xff0c;将其替换…

Java 网络编程之TCP(三):基于NIO实现服务端,BIO实现客户端

前面的文章&#xff0c;我们讲述了BIO的概念&#xff0c;以及编程模型&#xff0c;由于BIO中服务器端的一些阻塞的点&#xff0c;导致服务端对于每一个客户端连接&#xff0c;都要开辟一个线程来处理&#xff0c;导致资源浪费&#xff0c;效率低。 为此&#xff0c;Linux 内核…