zoukankan      html  css  js  c++  java
  • ASP.NET Web API通过ActionFilter来实现缓存

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Threading;
     5 using System.Threading.Tasks;
     6 using System.Web;
     7 using System.Web.Caching;
     8 using System.Web.Http;
     9 using System.Web.Http.Controllers;
    10 using System.Web.Http.Filters;
    11 
    12 namespace WebApi
    13 {
    14     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    15     public class CacheAttribute : ActionFilterAttribute
    16     {
    17         public string AbsoluteExpiration { get; set; }
    18         public string SlidingExpiration { get; set; }
    19         public CacheItemPriority Priority { get; set; }
    20 
    21         public CacheAttribute()
    22         {
    23             Priority = CacheItemPriority.Normal;
    24         }
    25 
    26         public override void OnActionExecuting(HttpActionContext actionContext)
    27         {
    28             var actionDescriptor = actionContext.ActionDescriptor as ReflectedHttpActionDescriptor;
    29             if (null == actionDescriptor)
    30             {
    31                 base.OnActionExecuting(actionContext);
    32             }
    33             var key = new CacheKey(actionDescriptor.MethodInfo, actionContext.ActionArguments);
    34             var array = HttpRuntime.Cache.Get(key.ToString()) as object[];
    35             if (null == array)
    36             {
    37                 base.OnActionExecuting(actionContext);
    38                 return;
    39             }
    40             var value = array.Any() ? array[0] : null;
    41             var actionResult = value as IHttpActionResult;
    42             if (null != actionResult)
    43             {
    44                 actionContext.Response = actionResult.ExecuteAsync(CancellationToken.None).Result;
    45                 return;
    46             }
    47             actionContext.Response = actionDescriptor.ResultConverter.Convert(actionContext.ControllerContext, value);
    48         }
    49     }
    50 
    51     public class CacheableActionDescriptor : ReflectedHttpActionDescriptor
    52     {
    53         private CacheAttribute CacheAttribute { get; }
    54 
    55         public CacheableActionDescriptor(ReflectedHttpActionDescriptor actionDescriptor, CacheAttribute cacheAttribute) : base(actionDescriptor.ControllerDescriptor, actionDescriptor.MethodInfo)
    56         {
    57             CacheAttribute = cacheAttribute;
    58         }
    59 
    60         public override Task<object> ExecuteAsync(HttpControllerContext controllerContext, IDictionary<string, object> arguments, CancellationToken cancellationToken)
    61         {  
    62             var absoluteExpiration = Cache.NoAbsoluteExpiration;
    63             var slidingExpiration = Cache.NoSlidingExpiration;
    64             var priority = CacheAttribute.Priority;
    65             if (!string.IsNullOrWhiteSpace(CacheAttribute.AbsoluteExpiration))
    66             {
    67                 absoluteExpiration = DateTime.Now + TimeSpan.Parse(CacheAttribute.AbsoluteExpiration);
    68             }
    69             if (!string.IsNullOrWhiteSpace(CacheAttribute.SlidingExpiration))
    70             {
    71                 slidingExpiration = TimeSpan.Parse(CacheAttribute.SlidingExpiration);
    72             }
    73             var cacheKey = new CacheKey(MethodInfo, arguments);
    74             var result = base.ExecuteAsync(controllerContext, arguments, cancellationToken).Result;
    75             HttpRuntime.Cache.Insert(cacheKey.ToString(), new[] {result}, null, absoluteExpiration, slidingExpiration, priority, null);
    76             return Task.FromResult(result);
    77         }
    78     }
    79 
    80     public class CacheableActionSelector : ApiControllerActionSelector
    81     {
    82         public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
    83         {
    84             var actionDescriptor = base.SelectAction(controllerContext);
    85             var reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor;
    86             if (null == reflectedActionDescriptor)
    87             {
    88                 return actionDescriptor;
    89             }
    90             var cacheAttribute = reflectedActionDescriptor.GetCustomAttributes<CacheAttribute>().FirstOrDefault() ??
    91                                  reflectedActionDescriptor.ControllerDescriptor.GetCustomAttributes<CacheAttribute>().FirstOrDefault();
    92             if (null == cacheAttribute)
    93             {
    94                 return actionDescriptor;
    95             }
    96             return new CacheableActionDescriptor(reflectedActionDescriptor, cacheAttribute);
    97         }
    98     }
    99 }

    注册ActionSelector

     1 using System;
     2 using System.Web;
     3 using System.Web.Http;
     4 using System.Web.Http.Controllers;
     5 using WebApi;
     6 
     7 namespace WebHost
     8 {
     9     public class Global : HttpApplication
    10     {
    11         protected void Application_Start(object sender, EventArgs e)
    12         {
    13             // 注册ASP.NET Web API路由
    14             GlobalConfiguration.Configuration.Routes.MapHttpRoute("default", "api/{controller}/{id}", new { id = RouteParameter.Optional });
    15 
    16 
    17             // 注册CacheableActionSelector
    18             GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionSelector), new CacheableActionSelector());
    19         }
    20     }
    21 }

    使用CacheAttribute

    1     public class DemoController : ApiController
    2     {
    3         [Cache(AbsoluteExpiration = "00:00:02", SlidingExpiration = "", Priority = CacheItemPriority.High)]
    4         public DateTime Get()
    5         {
    6             return DateTime.Now;
    7         }
    8     }
  • 相关阅读:
    hadoop2.2编程:MRUnit测试
    TestLinkConverter编程纪要
    Redisson的分布式锁的简单实现
    Jmeter工具使用
    JVM的学习(三)
    Mybatis需要注意的地方及知识点
    JVM学习二(JAVA的四种引用)
    mysql的引擎
    JVM学习一(JVM的内存结构和垃圾回收)
    JDk1.8HashMap的源码分析
  • 原文地址:https://www.cnblogs.com/frankyou/p/5123812.html
Copyright © 2011-2022 走看看