标签:
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 }
ASP.NET Web API通过ActionFilter来实现缓存
标签:
原文地址:http://www.cnblogs.com/frankyou/p/5123812.html