在asp.net web api中利用过滤器设置输出缓存
介绍
本文将介绍如何在asp.net web api中利用过滤器属性实现缓存。
实现过程
1,首先在web.config文件下appsettings下定义“CacheEnabled”和“CacheTimespan”两个属性,
CacheEnabled属性决定是否启用缓存
CacheTimespan决定缓存过期时间戳
如下代码所示:

<appSettings>
<!--<add key="webpages:Version" value="2.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />-->
<add key="CacheEnabled" value="true"/>
<add key="CacheTimespan" value="12000"/>
</appSettings>

2,添加WebApiOutputCacheAttribute类并继承ActionFilterAttribute ,需要添加引用:
using System.Net.Http;
using System.Web.Configuration;
using System.Net.Http.Headers;
using System.Net.Http.Formatting;
代码相当简单和直白,就是在get方法执行前判断缓存key存在不存在,如果存在读取value,并输出,在过滤器执行完后更新缓存,如果不存在刚直接调用api中get方法,输出结果。

public class WebApiOutputCacheAttribute :System.Web.Http.Filters.ActionFilterAttribute
{
// cache length in seconds
private int _timespan;
// true to enable cache
private bool _cacheEnabled = false;
// true if the cache depends on the caller user
private readonly bool _dependsOnIdentity;
// cache repository
private static readonly ObjectCache WebApiCache = MemoryCache.Default;
//private readonly SecurityHelper _securityHelper;
private readonly bool _invalidateCache; /// <summary>
/// Constructor
/// </summary>
public WebApiOutputCacheAttribute()
: this(true)
{
} /// <summary>
/// Constructor
/// </summary>
/// <param name="dependsOnIdentity"></param>
public WebApiOutputCacheAttribute(bool dependsOnIdentity)
: this(dependsOnIdentity, false)
{
} /// <summary>
/// Constructor
/// </summary>
/// <param name="dependsOnIdentity"></param>
/// <param name="invalidateCache">true to invalidate cache object</param>
public WebApiOutputCacheAttribute(bool dependsOnIdentity, bool invalidateCache)
{
//_securityHelper = new SecurityHelper();
_dependsOnIdentity = dependsOnIdentity;
_invalidateCache = invalidateCache; ReadConfig();
} /// <summary>
/// Called by the ASP.NET MVC framework before the action method executes.
/// </summary>
/// <param name="filterContext">The filter context.</param>
public override void OnActionExecuting(HttpActionContext filterContext)
{
if (_cacheEnabled)
{
if (filterContext != null)
{
if (IsCacheable(filterContext))
{
string _cachekey = string.Join(":", new string[]
{
filterContext.Request.RequestUri.OriginalString,
filterContext.Request.Headers.Accept.FirstOrDefault().ToString(),
}); //if (_dependsOnIdentity)
// _cachekey = _cachekey.Insert(0, _securityHelper.GetUser()); if (WebApiCache.Contains(_cachekey))
{
//TraceManager.TraceInfo(String.Format("Cache contains key: {0}", _cachekey)); var val = (string)WebApiCache.Get(_cachekey);
if (val != null)
{
filterContext.Response = filterContext.Request.CreateResponse();
filterContext.Response.Content = new StringContent(val);
var contenttype = (MediaTypeHeaderValue)WebApiCache.Get(_cachekey + ":response-ct");
if (contenttype == null)
contenttype = new MediaTypeHeaderValue(_cachekey.Split(':')[1]);
filterContext.Response.Content.Headers.ContentType = contenttype;
return;
}
}
}
}
else
{
throw new ArgumentNullException("actionContext");
}
}
} /// <summary>
/// Called by the ASP.NET MVC framework after the action method executes.
/// </summary>
/// <param name="filterContext">The filter context.</param>
public override void OnActionExecuted(HttpActionExecutedContext filterContext)
{
try
{
if (_cacheEnabled)
{
if (WebApiCache != null)
{
string _cachekey = string.Join(":", new string[]
{
filterContext.Request.RequestUri.OriginalString,
filterContext.Request.Headers.Accept.FirstOrDefault().ToString(),
}); //if (_dependsOnIdentity)
// _cachekey = _cachekey.Insert(0, _securityHelper.GetUser()); if (filterContext.Response != null && filterContext.Response.Content != null)
{
string body = filterContext.Response.Content.ReadAsStringAsync().Result; if (WebApiCache.Contains(_cachekey))
{
WebApiCache.Set(_cachekey, body, DateTime.Now.AddSeconds(_timespan));
WebApiCache.Set(_cachekey + ":response-ct", filterContext.Response.Content.Headers.ContentType, DateTime.Now.AddSeconds(_timespan));
}
else
{
WebApiCache.Add(_cachekey, body, DateTime.Now.AddSeconds(_timespan));
WebApiCache.Add(_cachekey + ":response-ct", filterContext.Response.Content.Headers.ContentType, DateTime.Now.AddSeconds(_timespan));
}
}
}
} if (_invalidateCache)
{
CleanCache();
}
}
catch (Exception ex)
{
//TraceManager.TraceError(ex);
}
} /// <summary>
/// Removes all items from the cache
/// </summary>
private static void CleanCache()
{
if (WebApiCache != null)
{
List<string> keyList = WebApiCache.Select(w => w.Key).ToList();
foreach (string key in keyList)
{
WebApiCache.Remove(key);
}
}
} private void ReadConfig()
{
if (!Boolean.TryParse(WebConfigurationManager.AppSettings["CacheEnabled"], out _cacheEnabled))
_cacheEnabled = false; if (!Int32.TryParse(WebConfigurationManager.AppSettings["CacheTimespan"], out _timespan))
_timespan = 1800; // seconds
} private bool IsCacheable(HttpActionContext ac)
{
if (_timespan > 0)
{
if (ac.Request.Method == HttpMethod.Get)
return true;
}
else
{
throw new InvalidOperationException("Wrong Arguments");
}
return false;
}
}

在api中:
// GET api/values/5
[WebApiOutputCacheAttribute(true)]
public string Get(int id)
{
return DateTime.Now.ToString();
}
在asp.net web api中利用过滤器设置输出缓存的更多相关文章
- 利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
在Asp.net Web API中,对业务数据的分页查询处理是一个非常常见的接口,我们需要在查询条件对象中,定义好相应业务的查询参数,排序信息,请求记录数和每页大小信息等内容,根据这些查询信息,我们在 ...
- ASP.NET Web API中的Controller
虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...
- 在ASP.NET Web API中使用OData
http://www.alixixi.com/program/a/2015063094986.shtml 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在A ...
- 【ASP.NET Web API教程】4.3 ASP.NET Web API中的异常处理
原文:[ASP.NET Web API教程]4.3 ASP.NET Web API中的异常处理 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...
- 【ASP.NET Web API教程】4.1 ASP.NET Web API中的路由
原文:[ASP.NET Web API教程]4.1 ASP.NET Web API中的路由 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容. ...
- ASP.NET Web API中使用OData
在ASP.NET Web API中使用OData 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在ASP.NET Web API中,对于CRUD(creat ...
- ASP.NET Web API中的JSON和XML序列化
ASP.NET Web API中的JSON和XML序列化 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok ...
- 目标HttpController在ASP.NET Web API中是如何被激活的:目标HttpController的创建
目标HttpController在ASP.NET Web API中是如何被激活的:目标HttpController的创建 通过上面的介绍我们知道利用HttpControllerSelector可以根据 ...
- 目标HttpController在ASP.NET Web API中是如何被激活的:目标HttpController的选择
目标HttpController在ASP.NET Web API中是如何被激活的:目标HttpController的选择 ASP.NET Web API能够根据请求激活目标HttpController ...
随机推荐
- 【转】消除代码中的 if-else/switch-case
在很多时候,我们代码中会有很多分支,而且分支下面的代码又有一些复杂的逻辑,相信很多人都喜欢用 if-else/switch-case 去实现.做的不好的会直接把实现的代码放在 if-else/swit ...
- Hibernate入门(六)---------HQL语句
Query: 代表面向对象的一个Hibernate查询操作.在Hibernate中,通常使用session.createQuery()方法接收一个HQL语句,然后调用Query的 list()或uni ...
- js 数据类型具体分析
复习 点运算符 xxx.sss xxx是对象 sss是属性和方法.任何数据类型都是拥有属性和方法的.字符串 String var st=“hello world”.字符串的定义 ...
- IP是什么 DNS 域名与IP有什么不同
IP地址是在网络上分配给每台计算机或网络设备的32位数字标识.在Internet上,每台计算机或网络设备的IP地址是全世界唯一的.IP地址的格式是 xxx.xxx.xxx.xxx,其中xxx是 0 到 ...
- vim 中:wq和:wq的不同之处
- DOM技术
DOM概述 DOM:Document Object Model(文档对象模型)(DOM核心就是 文档变对象,标签也变对象,属性也变对象,反正就是把标记文档拆散) 用来将标记型对象封装成对象,并将标记型 ...
- K8S Calico
NetworkPolicy是kubernetes对pod的隔离手段,是宿主机上的一系列iptables规则. Egress 表示出站流量,就是pod作为客户端访问外部服务,pod地址作为源地址.策略可 ...
- Vue2 几种常见开局方式
在SF问题中看到了一个关于vue-cli中的template问题,问题是这样的:用vue-cli工具生成的main.js中: import Vue from 'vue' import App from ...
- CSS3动画:流彩文字效果+图片模糊效果+边框伸展效果实现
前言 首先第一步,先布局html代码如下: <div class="wrap"> <img src="images/1.jpg" class= ...
- Javascript数组系列三之迭代方法2
今天我们来继续 Javascript 数组系列的文章,上文 <Javascript数组系列二之迭代方法1> 我们说到一些数组的迭代方法,我们在开发项目实战的过程中熟练的使用可以大大提高我们 ...