一、用过滤实现一个 当程序发生错误的时候,执行另一个方法的功能
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" }; } } }