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. Oracle数据库管理员面试题

    Oracle数据库管理员面试题 1.模拟使用oracle的flashback找回过去某个时间点的数据,实现误操作的恢复. http://www.txw100.com/soft/2013/08/547. ...

  2. wav 转换到 flac

    参考自:http://so.trust.blog.163.com/blog/static/17188620020127197618621/ wav  无损无压缩: flac无损压缩 将 wav 转换到 ...

  3. 图解 & 深入浅出 JavaWeb:Servlet 再说几句

    Writer      :BYSocket(泥沙砖瓦浆木匠) 微         博:BYSocket 豆         瓣:BYSocket FaceBook:BYSocket Twitter   ...

  4. JSONP跨域请求数据报错 “Unexpected token :”的解决办法

    原文  http://www.cnphp6.com/archives/65409 Jquery使用ajax方法实现jsonp跨域请求数据的时候报错 “Uncaught SyntaxError: Une ...

  5. IPv4分析

    IPv4的头部格式: 1. Version 版本号,默认是4. 2. IHL(Internet Header Length) 就是IPv4头部长度.这个长度的单位是32bit,一般是5,那么头部的长度 ...

  6. 探究MaxxBass音效

    MaxxBass是什么?官方的介绍是这样的: — Patented Waves MaxxBass psycho-acoustic bassextension delivers a more natur ...

  7. 基于Eclipse搭建Hadoop源码环境

    Hadoop使用ant+ivy组织工程,无法直接导入Eclipse中.本文将介绍如何基于Eclipse搭建Hadoop源码环境. 准备工作 本文使用的操作系统为CentOS.需要的软件版本:hadoo ...

  8. 重构第3天:方法提公(Pull Up Method)

    理解:方法提公,或者说把方法提到基类中. 详解:如果大于一个继承类都要用到同一个方法,那么我们就可以把这个方法提出来放到基类中.这样不仅减少代码量,而且提高了代码的重用性. 看重构前的代码: usin ...

  9. 编译安装 LLVM

    本文记录 LLVM 的安装过程,比较繁琐,使用 LLVM 3.4 操作系统:CentOS 6.6 64 位 1. 下载需要的软件 相关软件下载地址:http://llvm.org/releases/d ...

  10. rm: 无法删除&quot;/run/user/root/gvfs&quot;: 是一个目录 问题

    2013-03-02    bxd@linux:~$ sudo su [sudo] password for bxd:  root@linux:/home/bxd# exit exit rm: 无法删 ...