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. WPF自定义控件

    一.ImageButton 1.继承ImageButtonButton,添加依赖属性 using System; using System.Windows; using System.Windows. ...

  2. cmd窗口编码方式的修改

    cmd默认的编码是采用GBK   regedit HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe\CodePage 十进制:936 GB ...

  3. 二十四、【开源】EFW框架Winform前端开发之项目结构说明和调试方法

    回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.2:http://pan.baidu.com/s/1hcnuA EFW框架实例源代码下载:http://pan ...

  4. Windows无法安装到GPT分区形式磁盘,怎么办?

    有时候用原版系统镜像安装windows系统时,会提示“windows无法安装到这个磁盘.选中的磁盘采用GPT分区形式”,导致安装失败,下面就来讲解一下如何解决. 步骤阅读   百度经验:jingyan ...

  5. ubuntu remove mysql

    ubuntu 彻底删除 mysql 然后重装 mysql 删除 mysql sudo apt-get autoremove --purge mysql-server-5.0sudo apt-get r ...

  6. 菜鸟学Windows Phone 8开发(4)——设置应用程序样式

    本系列文章来源MSDN的 面向完全新手的 Windows Phone 8 开发  本文地址:http://channel9.msdn.com/Series/Windows-Phone-8-Develo ...

  7. ruby -- 进阶学习(十四)设置background-image(解决无法获取图片路径问题)

    基于rails4.0环境 为了美化界面,添加背景图片,于是又傻逼了一回~~ 一开始在xxx.html.erb中添加:(注:图片的路径为:app/asssets/images/background.jp ...

  8. 编写高质量JS代码的68个有效方法(十二)

    No.56.避免不必要的状态 Tips: 尽可能地使用无状态的API 如果API是有状态的,标示出每个操作与哪些状态有关联 无状态的API简洁,更容易学习和使用,也不需要考虑其他的状态.如: 'tes ...

  9. 【转载】Grunt常用插件介绍

    项目名称 grunt-contrib v0.8.0 项目地址 https://github.com/gruntjs/grunt-contrib 项目介绍 此项目是对grunt常用插件的集合,刚接触gr ...

  10. [Python] Symbol Review

    From:http://learnpythonthehardway.org/book/ex37.html 1. with X as Y: pass 1.1 yield 2. exec 2.1 name ...