目录
一:多种注册方式
在不修改之前代码为基础,动态增加功能。
1:当前方法注册:仅对当前方法生效
/// <summary>
/// Get请求
/// 当前方法注册如:应用ResourceFilter扩展
/// Home控制器的Index
/// </summary>
/// <returns>Index视图</returns>
[HttpGet]
[当前方法注册如:ResourceFilter]
public IActionResult Index()
{
return View();
}
2:当前控制器注册:仅对当前控制器生效
using Microsoft.AspNetCore.Mvc;
using NLog.Web.LayoutRenderers;
using Study_ASP.NET_Core_MVC.Models;
using Study_ASP.NET_Core_MVC.Utility.Filters;
using System.Diagnostics;
namespace Study_ASP.NET_Core_MVC.Controllers
{
/// <summary>
/// 当前控制器注册如:ResourceFilter扩展
/// </summary>
[当前控制器注册如:ResourceFilter]
public class HomeController : Controller
{
/// <summary>
/// Get请求
/// Home控制器的Index
/// </summary>
/// <returns>Index视图</returns>
[HttpGet]
public IActionResult Index()
{
return View();
}
}
}
3:全局注册:在Program.cs类中全局注册
using Study_ASP.NET_Core_MVC.Utility.Filters;
//表示整个应用程序,调用CreateBuilder方法创建一个WebApplicationBuilder对象。
//初始化当前应用程序的管道容器
var builder = WebApplication.CreateBuilder(args);
//添加全局注册AOP方法ResourceFilter扩展
builder.Services.AddControllersWithViews(MvcOptions =>
{
MvcOptions.Filters.Add<ResourceFilter>();
});
二:匿名扩展
关键类AllowAnonymous类代码:
namespace Study_ASP.NET_Core_MVC.Utility.Filters
{
public class AllowAnonymous:Attribute
{
}
}
控制器代码:
using Microsoft.AspNetCore.Mvc;
using NLog.Web.LayoutRenderers;
using Study_ASP.NET_Core_MVC.Models;
using Study_ASP.NET_Core_MVC.Utility.Filters;
using System.Diagnostics;
namespace Study_ASP.NET_Core_MVC.Controllers
{
/// <summary>
/// 当前控制器注册如:ResourceFilter扩展
/// </summary>
[当前控制器注册如:ResourceFilter]
public class HomeController : Controller
{
/// <summary>
/// Get请求
/// 当前方法注册如:应用ResourceFilter扩展
/// 使用AllowAnonymous排除当前ResourceFilter扩展
/// Home控制器的Index
/// </summary>
/// <returns>Index视图</returns>
[HttpGet]
[当前方法注册如:ResourceFilter]
[AllowAnonymous]
public IActionResult Index()
{
return View();
}
}
}
扩展IResourceFilter不能直接使用AllowAnonymousAttribute需要扩展支持
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace Study_ASP.NET_Core_MVC.Utility.Filters
{
public class ResourceFilter : Attribute, IResourceFilter
{
/// <summary>
/// 初始化缓存构造函数
/// </summary>
private static Dictionary<string, object> CacheDictionary = new Dictionary<string, object>();
/// <summary>
/// 在XXX资源之前
/// </summary>
/// <param name="context"></param>
public void OnResourceExecuting(ResourceExecutingContext context)
{
//判断当前方法或控制器上是否存在排除特性AllowAnonymous
if (context.ActionDescriptor.EndpointMetadata.Any(c => c.GetType().Equals(typeof(AllowAnonymous))))
{
return;
}
string pathKey = context.HttpContext.Request.Path;
if (CacheDictionary.ContainsKey(pathKey))
{
context.Result = (IActionResult)CacheDictionary[pathKey];
}
Console.WriteLine("CustomResourceFilterAttribute.OnResourceExecuting方法");
}
/// <summary>
/// 在XXX资源之后
/// </summary>
/// <param name="context"></param>
public void OnResourceExecuted(ResourceExecutedContext context)
{
//判断当前方法或控制器上是否存在排除特性AllowAnonymous
if (context.ActionDescriptor.EndpointMetadata.Any(c => c.GetType().Equals(typeof(AllowAnonymous))))
{
return;
}
string pathKey = context.HttpContext.Request.Path;
CacheDictionary[pathKey] = context.Result;
Console.WriteLine("CustomResourceFilterAttribute.OnResourceExecuted方法");
}
}
}
扩展IActionFilter不能直接使用AllowAnonymousAttribute需要扩展支持
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using Study_ASP.NET_Core_MVC.Controllers;
namespace Study_ASP.NET_Core_MVC.Utility.Filters
{
public class ActionFilter : Attribute, IActionFilter
{
/// <summary>
/// 初始化构造函数
/// </summary>
private readonly ILogger<ActionFilter> _logger;
public ActionFilter(ILogger<ActionFilter> logger)
{
_logger = logger;
}
/// <summary>
/// 在XXX执行之前
/// </summary>
/// <param name="context"></param>
public void OnActionExecuting(ActionExecutingContext context)
{
//判断当前方法或控制器上是否存在排除特性AllowAnonymous
if (context.ActionDescriptor.EndpointMetadata.Any(c => c.GetType().Equals(typeof(AllowAnonymous))))
{
return;
}
var controller = context.HttpContext.GetRouteValue("Controller");
var action = context.HttpContext.GetRouteValue("Action");
var param = context.HttpContext.Request.QueryString.Value;
_logger.LogInformation($"当前请求的控制器:{controller},方法:{action},请求参数:{JsonConvert.SerializeObject(param)}");
}
/// <summary>
/// 在XXX执行之后
/// </summary>
/// <param name="context"></param>
public void OnActionExecuted(ActionExecutedContext context)
{
//判断当前方法或控制器上是否存在排除特性AllowAnonymous
if (context.ActionDescriptor.EndpointMetadata.Any(c => c.GetType().Equals(typeof(AllowAnonymous))))
{
return;
}
var controller = context.HttpContext.GetRouteValue("Controller");
var action = context.HttpContext.GetRouteValue("Action");
var param = context.Result;
_logger.LogInformation($"当前请求的控制器:{controller},方法:{action},请求结果:{JsonConvert.SerializeObject(param)}");
}
}
}
扩展IResultFilter不能直接使用AllowAnonymousAttribute需要扩展支持
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Study_ASP.NET_Core_MVC.Models;
namespace Study_ASP.NET_Core_MVC.Utility.Filters
{
public class ResultFilter : Attribute, IResultFilter
{
/// <summary>
/// 在XXX执行之前
/// </summary>
/// <param name="context"></param>
/// <exception cref="NotImplementedException"></exception>
public void OnResultExecuting(ResultExecutingContext context)
{
//判断当前方法或控制器上是否存在排除特性AllowAnonymous
if (context.ActionDescriptor.EndpointMetadata.Any(c => c.GetType().Equals(typeof(AllowAnonymous))))
{
return;
}
if (context.Result is JsonResult)
{
JsonResult result = (JsonResult)context.Result;
context.Result = new JsonResult(new AjaxResult()
{
Success = true,
Message="Ok",
Data = result.Value
});
}
}
/// <summary>
/// 在XXX执行之后
/// </summary>
/// <param name="context"></param>
/// <exception cref="NotImplementedException"></exception>
public void OnResultExecuted(ResultExecutedContext context)
{
//判断当前方法或控制器上是否存在排除特性AllowAnonymous
if (context.ActionDescriptor.EndpointMetadata.Any(c => c.GetType().Equals(typeof(AllowAnonymous))))
{
return;
}
Console.WriteLine("在XXX执行之后ResultFilter.OnResultExecuted方法");
}
}
}
三:Filter使用环境
权限验证:AuthorizeAttribute:常用于验证用户身份和权限。
资源缓存:IResourceFilter和IAsyncResourceFilter:常用于资源缓存。如果被缓存,将继续执行。如果没有被缓存,将数据进行缓存再继续执行。
方法前后记录:IActionFilter和IAsyncActionFilter:常用于记录日志,搭配Log4Net或NLog效果更佳。
结果生成前后扩展:IResultFilter和IAsyncResultFilter:常用于渲染视图或处理Json数据或Ajax数据结果。
响应结果补充:IAlwaysRunResultFilter:常用于响应结果,利用IAlwaysRunResultFilter或IAsyncAlwaysRunResultFilter特性让程序继续执行。
异常处理:IExceptionFilter和IAsyncExceptionFilter:常用于处理程序异常。
四:Filter生命周期
- 执行权限验证:Authorization
- 执行资源缓存:ResourceFilter.OnResourceExecuting方法
- 执行控制器实例
- 执行方法前后记录:ActionFilter.OnActionExecuting方法
- 执行Action方法
- 执行方法前后记录:ActionFilter.OnActionExecuted方法
- 执行结果生成前后扩展:ResultFilter.OnResultExecuting方法
- 执行响应结果补充:AlwaysRunResultFilter.OnResultExecuting方法
- 渲染视图
- 执行响应结果补充:AlwaysRunResultFilter.OnResultExecuted方法
- 执行结果生成前后扩展:ResultFilter.OnResultExecuted方法
- 执行资源缓存:ResourceFilter.OnResourceExecuted方法
五:不同注册执行顺序:分别为全局注册、控制器注册、Action注册
- 全局注册开始
- 控制器注册开始
- Action注册开始
- Action执行
- Action注册结束
- 控制器注册结束
- 全局注册结束