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. saiku执行速度优化二

    上一篇文章介绍了添加filter可以加快查询速度.下面继续分析: 下面这个MDX语句: WITH SET [~FILTER] AS {[create_date].[create_date].[--]} ...

  2. Android JNI 之 JNIEnv 解析

    jni.h文件 : 了解 JNI 需要配合 jni.h 文件, jni.h 是 Google NDK 中的一个文件, 位置是 $/android-ndk-r9d/platforms/android-1 ...

  3. Microsoft 2013 新技术学习笔记 二

    在探讨系统重构的代码结构组织之前,先初步考虑框架与数据库的交互,在.net平台上数据访问方案有人总结为三类:DataSet.ADO.net 2.0.ORM组件.我只熟悉ADO.NET方式,众多的企业特 ...

  4. Android开发中内存和UI优化

    1.内存||效率 GC这东西对于开发人员用起来比较爽,但对于技术总监或产品总监来说,他们并不在乎,在乎的是用户运行App的流畅度,待你开发完了,笑眯眯的走过来,让你测试N个适配器,烦都烦死你. 说到这 ...

  5. MemCached用法

    所需要的jar包: com.danga.MemCached.MemCachedClient com.danga.MemCached.SockIOPool 自行下载/** * 缓存服务器集群,提供缓存连 ...

  6. 让mingw gdb支持STL,并自动load .gdbinit

    环境要求:python (2.7版本可以,3.x没测过),mingw官方版(你可能已经有了),gdb2013-02-04(到这里https://code.google.com/p/qp-gcc/dow ...

  7. 电商大促准备流程v2

    1 概述 对于电商企业而言,每年都会有几次大的促销活动,像双十一.店庆等,对于第一次参加这个活动的新手,难免会有些没有头绪,因而将自己参加双十一.双十二活动中的过程心得进行下总结,一方面供以后工作中继 ...

  8. 解析表达式到lucene.net的Query

    查询的时候有自己的查询格式,为了统一并且方便的搜索lucene.net 于是就写了个解析格式,大体上覆盖了几乎所有的lucene.net的query了.当然少了公共扩展库里包含的regexQuery, ...

  9. Docker练习例子:基于 VNCServer + noVNC 构建 Docker 桌面系统

    0. 安装docker 这一步略,网上有好多教程,一般出现装不上的原因,也就是网速问题了,这个我也很难帮你. 1. 下载指定的镜像images docker pull dorowu/ubuntu-de ...

  10. Web Component--01. 简介

    Web Components 是什么? Web Components是W3C定义的新标准,它给了前端开发者扩展浏览器标签的能力,可以自由的定制组件,更好的进行模块化开发,彻底解放了前端开发者的生产力. ...