using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Caching;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters; namespace WebApi
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CacheAttribute : ActionFilterAttribute
{
public string AbsoluteExpiration { get; set; }
public string SlidingExpiration { get; set; }
public CacheItemPriority Priority { get; set; } public CacheAttribute()
{
Priority = CacheItemPriority.Normal;
} public override void OnActionExecuting(HttpActionContext actionContext)
{
var actionDescriptor = actionContext.ActionDescriptor as ReflectedHttpActionDescriptor;
if (null == actionDescriptor)
{
base.OnActionExecuting(actionContext);
}
var key = new CacheKey(actionDescriptor.MethodInfo, actionContext.ActionArguments);
var array = HttpRuntime.Cache.Get(key.ToString()) as object[];
if (null == array)
{
base.OnActionExecuting(actionContext);
return;
}
var value = array.Any() ? array[] : null;
var actionResult = value as IHttpActionResult;
if (null != actionResult)
{
actionContext.Response = actionResult.ExecuteAsync(CancellationToken.None).Result;
return;
}
actionContext.Response = actionDescriptor.ResultConverter.Convert(actionContext.ControllerContext, value);
}
} public class CacheableActionDescriptor : ReflectedHttpActionDescriptor
{
private CacheAttribute CacheAttribute { get; } public CacheableActionDescriptor(ReflectedHttpActionDescriptor actionDescriptor, CacheAttribute cacheAttribute) : base(actionDescriptor.ControllerDescriptor, actionDescriptor.MethodInfo)
{
CacheAttribute = cacheAttribute;
} public override Task<object> ExecuteAsync(HttpControllerContext controllerContext, IDictionary<string, object> arguments, CancellationToken cancellationToken)
{
var absoluteExpiration = Cache.NoAbsoluteExpiration;
var slidingExpiration = Cache.NoSlidingExpiration;
var priority = CacheAttribute.Priority;
if (!string.IsNullOrWhiteSpace(CacheAttribute.AbsoluteExpiration))
{
absoluteExpiration = DateTime.Now + TimeSpan.Parse(CacheAttribute.AbsoluteExpiration);
}
if (!string.IsNullOrWhiteSpace(CacheAttribute.SlidingExpiration))
{
slidingExpiration = TimeSpan.Parse(CacheAttribute.SlidingExpiration);
}
var cacheKey = new CacheKey(MethodInfo, arguments);
var result = base.ExecuteAsync(controllerContext, arguments, cancellationToken).Result;
HttpRuntime.Cache.Insert(cacheKey.ToString(), new[] {result}, null, absoluteExpiration, slidingExpiration, priority, null);
return Task.FromResult(result);
}
} public class CacheableActionSelector : ApiControllerActionSelector
{
public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
{
var actionDescriptor = base.SelectAction(controllerContext);
var reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor;
if (null == reflectedActionDescriptor)
{
return actionDescriptor;
}
var cacheAttribute = reflectedActionDescriptor.GetCustomAttributes<CacheAttribute>().FirstOrDefault() ??
reflectedActionDescriptor.ControllerDescriptor.GetCustomAttributes<CacheAttribute>().FirstOrDefault();
if (null == cacheAttribute)
{
return actionDescriptor;
}
return new CacheableActionDescriptor(reflectedActionDescriptor, cacheAttribute);
}
}
}

注册ActionSelector

 using System;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using WebApi; namespace WebHost
{
public class Global : HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
// 注册ASP.NET Web API路由
GlobalConfiguration.Configuration.Routes.MapHttpRoute("default", "api/{controller}/{id}", new { id = RouteParameter.Optional }); // 注册CacheableActionSelector
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionSelector), new CacheableActionSelector());
}
}
}

使用CacheAttribute

     public class DemoController : ApiController
{
[Cache(AbsoluteExpiration = "00:00:02", SlidingExpiration = "", Priority = CacheItemPriority.High)]
public DateTime Get()
{
return DateTime.Now;
}
}

ASP.NET Web API通过ActionFilter来实现缓存的更多相关文章

  1. ASP.NET Web API中通过ETag实现缓存

    通常情况下Server是无状态的,在ASP.NET Web API中,我们可以让服务端响应体中产生ETag属性,起到缓存的作用.大致实现原理是: 1.服务端的响应体中返回一个ETag属性2.客户端通过 ...

  2. ASP.NET Web Api 使用CacheCow和ETag缓存资源(转载)

    转载地址:http://www.cnblogs.com/fzrain/p/3618887.html 前言 本文将使用一个开源框架CacheCow来实现针对Http请求资源缓存,本文主要介绍服务器端的缓 ...

  3. ASP.NET Web API实现缓存的2种方式

    在ASP.NET Web API中实现缓存大致有2种思路.一种是通过ETag, 一种是通过类似ASP.NET MVC中的OutputCache. 通过ETag实现缓存 首先安装cachecow.ser ...

  4. 8 种提升 ASP.NET Web API 性能的方法

    ASP.NET Web API 是非常棒的技术.编写 Web API 十分容易,以致于很多开发者没有在应用程序结构设计上花时间来获得很好的执行性能. 在本文中,我将介绍8项提高 ASP.NET Web ...

  5. 通过扩展让ASP.NET Web API支持W3C的CORS规范

    让ASP.NET Web API支持JSONP和W3C的CORS规范是解决"跨域资源共享"的两种途径,在<通过扩展让ASP.NET Web API支持JSONP>中我们 ...

  6. 新作《ASP.NET Web API 2框架揭秘》正式出版

    我觉得大部分人都是“眼球动物“,他们关注的往往都是目光所及的东西.对于很多软件从业者来说,他们对看得见(具有UI界面)的应用抱有极大的热忱,但是对背后支撑整个应用的服务却显得较为冷漠.如果我们将整个“ ...

  7. 如何让ASP.NET Web API的Action方法在希望的Culture下执行

    在今天编辑推荐的<Hello Web API系列教程--Web API与国际化>一文中,作者通过自定义的HttpMessageHandler的方式根据请求的Accep-Language报头 ...

  8. ASP.NET Web API 提升性能的方法实践

    ASP.NET Web API 是非常棒的技术.编写 Web API 十分容易,以致于很多开发者没有在应用程序结构设计上花时间来获得很好的执行性能. 在本文中,我将介绍8项提高 ASP.NET Web ...

  9. ASP.NET Web API 应用教程(一) ——数据流使用

    相信已经有很多文章来介绍ASP.Net Web API 技术,本系列文章主要介绍如何使用数据流,HTTPS,以及可扩展的Web API 方面的技术,系列文章主要有三篇内容. 主要内容如下: I  数据 ...

随机推荐

  1. OpenSSL Command-Line HOWTO

    OpenSSL Command-Line HOWTO The openssl application that ships with the OpenSSL libraries can perform ...

  2. Objective-C学习备忘录:Clang编译器编译运行Objective-C代码

    我们都知道可以通过Apple公司的Xcode工具来学习Objective-C编程语言,但是能不能脱离XCode这个IDE进行Objective-C学习呢?当然是可以的.首先作为计算机科班出身的程序员都 ...

  3. 本人独立博客:http://www.zjmainstay.cn

    为了方便各种管理,本人创建了独立博客,博客地址:http://www.zjmainstay.cn 欢迎新老朋友围观.

  4. 头文件 string.h cstring string 区别

    1.#include <cstring>   //不可以定义string s:可以用到strcpy等函数using   namespace   std; #include <stri ...

  5. managed_shared_memory.construct造成的性能损失

    boost中的IPC进程间通信非常好用,可以直接在共享内存上创建对象,相当于new分配器,实测发现它的分配算法还是有点耗时.第一个测试代码仅仅分配一次,然后频繁的复制,每秒钟可以复制4200次左右. ...

  6. Codeforces Round #184 (Div. 2) E. Playing with String(博弈)

    题目大意 两个人轮流在一个字符串上删掉一个字符,没有字符可删的人输掉游戏 删字符的规则如下: 1. 每次从一个字符串中选取一个字符,它是一个长度至少为 3 的奇回文串的中心 2. 删掉该字符,同时,他 ...

  7. VPN理论简单介绍(转载)

    标签:VPN理论简单介绍 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://lvnian.blog.51cto.com/715528 ...

  8. Ubuntu下PHP的扩展

    Ubuntu版本:14.04 1. 下载php-5.5.10.tar.bz2,并解压. 2.  终端进入解压后的目录php-5.5.10,运行configure.(输入命令./configure) 3 ...

  9. Android样式的开发:drawable汇总篇

    Android有很多种drawable类型,除了前几篇详细讲解的shape.selector.layer-list,还有上一篇提到的color.bitmap.clip.scale.inset.tran ...

  10. JS文档和Demo自动化生成工具 - SmartDoc发布

    曾几何时,当你码神附体,一路披荆斩棘的完成代码后,带着“一码在手,天下我有”的傲然环顾之时,却发现单元测试.API文档.Demo实例陆续向你砸来,顿时有木有一种冰水挑战后的感觉.而这时你应该:哟哟,快 ...