.net core webapi教程-Filter全局注册、控制器注册如何排除某些Action方法使其不生效
深山老妖浏览:11022023-12-04 15:25:48本文累计收益:0我也要赚钱

在使用Filter时,如果使用全局注册或者控制器注册(.net core webapi教程-Filter的多种注册方法),对程序所有Action或控制器内所有Action都是生效的,如何排除某些Action不生效呢?

系统提供了AllowAnonymousAttribute特性,但是有部分可以直接使用,有部分没法直接使用,需要自己编写代码进行扩展支持,本文讲解如何自己编写代码解决。

IResourceFiter、IActionFilter、IResultFilter三个Filter不能直接使用,需要扩展支持。

一、创建CustomAllowAnonymousAttribute特性类并继承自Attribute
namespace NetCoreStudy.WebApi.Utility.Filters
{
    public class CustomAllowAnonymousAttribute:Attribute
    {
    }
}
二、在Action方法标记特性使用特性
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using NetCoreStaty.BussinessInterface;
using NetCoreStudy.Model;
using NetCoreStudy.Utility;
using NetCoreStudy.WebApi.Utility.Filters;

namespace NetCoreStudy.WebApi.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    [ResourceFilter]
    public class FilterController : ControllerBase
    {
        private readonly IBookService _bookService;
        public FilterController(IBookService bookService) {
            _bookService = bookService;
        }
        [HttpGet]
        [CustomAllowAnonymous]
        public IActionResult ResultIndex()
        {
            var list = _bookService.Query<BookEntity>(c => true).ToList();
            return new JsonResult(new 
            {
                Id = 123,
                Name = "张三",
                Age = 34
            });
        }
    }
}
三、修改ResourceFilterAttribute代码支持CustomAllowAnonymousAttribute特性

CustomAllowAnonymousAttribute类自定义了一个特性,在ResourceFilterAttribute Filter实现类中获取Action上面是否标注了CustomAllowAnonymousAttribute特性,如果获取到说明方法有标记直接返回,代码如下:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace NetCoreStudy.WebApi.Utility.Filters
{
    public class ResourceFilterAttribute : Attribute, IResourceFilter
    {
        private static Dictionary<string, object> CacheDictionary = new Dictionary<string, object>();
        /// <summary>
        /// 在XX资源之前
        /// </summary>
        /// <param name="context"></param>
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            //context.ActionDescriptor.EndpointMetadata获取包含标记在当前要访问的Action上或者当前Action所在控制器
            //标记的所有的特性
            if (context.ActionDescriptor.EndpointMetadata.Any(c=>c.GetType().Equals(typeof(CustomAllowAnonymousAttribute))))
            {
                return;
            }
            //如果支持匿名,就不让这里的代码执行
            string key = context.HttpContext.Request.Path;
            if (CacheDictionary.ContainsKey(key))
            {
                //只要给Reslut赋值了,就会中断往后执行,直接返回给调用方
                context.Result = (IActionResult)CacheDictionary[key];
            }
            Console.WriteLine("在某某资源之前执行");
        }
        /// <summary>
        /// 在XX资源之后
        /// </summary>
        /// <param name="context"></param>
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            //context.ActionDescriptor.EndpointMetadata获取包含标记在当前要访问的Action上或者当前Action所在控制器
            //标记的所有的特性
            if (context.ActionDescriptor.EndpointMetadata.Any(c => c.GetType().Equals(typeof(CustomAllowAnonymousAttribute))))
            {
                return;
            }
            //如果支持匿名,就不让这里的代码执行
            //拿到执行结果,保存到缓存
            string key = context.HttpContext.Request.Path;
            CacheDictionary[key] = context.Result;
            Console.WriteLine("在某某资源之后执行");
        }
    }
}

 

评论列表
发表评论
+ 关注