一、AspNetCore中的过滤器(错误则调用另外方法||实现缓存)

 一、用过滤实现一个 当程序发生错误的时候,执行另一个方法的功能

1、控制器代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Common;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace ZanLveCore.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        /// <summary>
        /// 方法1
        /// </summary>
        /// <param name="data">传参数据</param>
        /// <returns></returns>
        [CoreExceptionFilter(nameof(TestController), nameof(GetData2))]
        [HttpGet("{data}")]  //必须{data} [HttpGet]则会报错
        public string GetData(string data)
        {
            throw new Exception();
        }
        /// <summary>
        /// 方法2
        /// </summary>
        /// <param name="data">传参数据</param>
        /// <returns></returns>
        [HttpGet]
        public ApiResultModels GetData2(string data)
        {
            var result = new ApiResultModels();
            result.Data = "";
            result.Message = "Token获取成功!";
            result.Code = "OK!";
            return result;
        }

    }

    public class UserModel
    {
        public int Delete(int id)
        {
            //记录日志
            //重新执行一遍代码
            return id;
        }
    }
}

2、过滤器方法

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace ZanLveCore
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]

    //继承IExceptionFilter 异常过滤器
    //继承IActionFilter 过滤器
    //继承Attribute 特性方法 ,方可使用 [CoreExceptionFilter(nameof(TestController), nameof(GetData2))] 通过 AttributeUsage接收    

    public class CoreExceptionFilter : Attribute, IExceptionFilter, IActionFilter  
    {
        /// <summary>
        /// 发生错误的时候重新执行的方法
        /// </summary>
        public string FallBackClass { get; set; }
        /// <summary>
        /// 发生错误的时候重新执行的方法
        /// </summary>
        public string FallBackMethod { get; set; }

        /// <summary>
        /// 获取方法的参数
        /// </summary>
        public object[] InvokeParameters { get; set; }

        /// <summary>
        /// 构造函数使用该类时参数为方法
        /// </summary>
        /// <param name="fallBackMethod"></param>
        public CoreExceptionFilter(string fallBackClass, string fallBackMethod)
        {
            this.FallBackMethod = fallBackMethod;
            this.FallBackClass = fallBackClass;
        }
        /// <summary>
        /// 使用新方法
        /// </summary>
        /// <param name="asm"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private object UseNewMethod(Assembly asm, object[] parameters)
        {
            Object obj = null;
            foreach (Type type in asm.GetExportedTypes())
            {
                if (type.Name == FallBackClass)
                {
                    obj = System.Activator.CreateInstance(type);
                    foreach (var item in type.GetMethods())
                    {
                        if (item.Name == FallBackMethod)
                        {
                            obj = type.GetMethod(FallBackMethod).Invoke(obj, parameters);
                        }
                    }
                }
            }
            return obj;
        }
        /// <summary>
        /// 获取所有被监控方法的参数
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuting(ActionExecutingContext context)
        {
            object[] parameters = new object[context.ActionArguments.Count];
            int Count = 0;
            foreach (var item in context.ActionArguments)
            {
                parameters[Count] = item.Value;
                Count++;
            }
            InvokeParameters = parameters;
        }

        /// <summary>
        /// 错误的时候执行新的方法
        /// </summary>
        /// <param name="context"></param>
        public void OnException(ExceptionContext context)
        {
            var objectResult = context.Exception as Exception;
            if (objectResult.Message != null)
            {
                context.Result = new ObjectResult(UseNewMethod(this.GetType().Assembly, InvokeParameters));
                //context.Result = new ObjectResult(new { Success = true, code = 200, msg = "成功", Data = UseNewMethod(this.GetType().Assembly, InvokeParameters) });
            }
        }
        public void OnActionExecuted(ActionExecutedContext context)
        {

        }
    }
}

 映射的方法调用方法

二、缓存实现(通过滤器的方式)

1、过滤器实现缓存类

代码如下:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Blog.Attributes
{
    /// <summary>
    /// 接口缓存
    /// </summary>
    public class WebApiCacheAttribute : ActionFilterAttribute
    {
        private static IMemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions());

        private bool cacheBool = true;
        /// <summary>
        /// 时间
        /// </summary>
        public int Duration { get; set; } = 3;
        /// <summary>
        /// 缓存key
        /// </summary>
        private string CacheKey { get; set; }

        /// <summary>
        ///  在Action方法调用前使用,使用场景:如何验证登录等。
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            CacheKey = $"{context.HttpContext.Request.Scheme}://{context.HttpContext.Request.Host.ToString()}{context.HttpContext.Request.PathBase}{context.HttpContext.Request.Path}{context.HttpContext.Request.QueryString.ToString()}";
            dynamic obj = memoryCache.Get(CacheKey);
            if (obj != null)
            {
                context.Result = new ObjectResult(obj);
                cacheBool = false;
            }
            else
            {
                lock (CacheKey)
                {
                    obj = memoryCache.Get(CacheKey);
                    if (obj != null)
                    {
                        context.Result = new ObjectResult(obj);
                        cacheBool = false;
                    }
                    else
                    {
                        cacheBool = true;
                        base.OnActionExecuting(context);
                    }
                }
            }
        }

        /// <summary>
        /// 在Action方法调用后,result方法调用前执行,使用场景:异常处理。
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuted(ActionExecutedContext context)
        {

        }

        /// <summary>
        /// 输出执行
        /// </summary>
        /// <param name="context"></param>
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            if (cacheBool)
            {
                if (context.Result is ObjectResult)
                {
                    var objectResult = context.Result as ObjectResult;
                    var obj = objectResult.Value;
                    memoryCache.Set<object>(CacheKey, obj, DateTime.Now.AddSeconds(Duration));
                }
            }
        }

        /// <summary>
        /// 在result执行后发生,使用场景:异常处理,页面尾部输出调试信息。
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnResultExecuted(ResultExecutedContext context)
        {

        }
    }
}

2、使用方法

 代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Blog.Attributes;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Blog.Controllers
{
    [Route("api/[controller]/[action]")]  //Api控制器
    [ApiController]
    public class HomeController : Controller
    {
        // GET: api/<controller>
        [HttpGet]
        [WebApiCache(Duration = 10)]//增加特性
        public IEnumerable<string> Get()
        {
            
            return new string[] { "value1", "value2" };
        }
    }
}
原文地址:https://www.cnblogs.com/fger/p/12105999.html