在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 ...
随机推荐
- 【Tomcat】上线部署tomcat。常用命令
ps -ef | grep tomcat-web [查询tomact进程]kill -9 pid [结束tomcat进程]/opt/tomcat-web/bin/startup.sh [启动tomca ...
- C#设计模式之二十职责链模式(Chain of Responsibility Pattern)【行为型】
一.引言 今天我们开始讲“行为型”设计模式的第八个模式,该模式是[职责链模式],英文名称是:Chain of Responsibility Pattern.让我们看看现实生活中的例子吧,理解起来可能更 ...
- 填一个laravel视图缓存没有及时更新的坑
1.此坑背景 laravel在渲染blade模板后,会将渲染好的结果存到storage/framework/views(默认路径,也可在配置中修改的)中,以便下次使用.但我最近总是发现修改了blade ...
- [Linux]lnmp一键安装包,访问yii/tp5/laravel的时候,报错500或者空白页面
当你将默认的访问路径改后(nginx.conf中的root 之后的路径),同时应该将/home/wwwroot/default/.user.ini 中的路径也改了! .user.ini 是隐藏文件,需 ...
- vue从入门到进阶:vue-router路由功能(九)
基本使用 html: <script src="https://unpkg.com/vue/dist/vue.js"></script> <scrip ...
- 2018-05-14 代码考古-Python3官方教程字典例程
知乎原链 Data Structures中的第一个例程: >>> tel = {'jack': 4098, 'sape': 4139} >>> tel['guido ...
- SAP FI配置步骤
http://blog.sina.com.cn/s/blog_8eda1a620100uwzj.html No. 配置对象 事务代码 配置内容 路径 备注 1 定义公司 OX15 企业结构>定义 ...
- Android的ToolBar
ToolBar比ActionBar更加可控,自由.因此,Google 逐渐使用ToolBar来代替ActionBar. 使用ToolBar 1.要引入appCompat_v7支持 2.主题设置为NoA ...
- 小程序实践(二):swiper组件实现轮播图效果
swiper组件类似于Android中的ViewPager,实现类似轮播图的效果,相对于Android的Viewpager,swiper实现起来更加方便,快捷. 效果图: 首先看下swiper支持的属 ...
- Android--获取手机联系人和Sim卡联系人
最近公司做的一个放贷APP,要求后台偷偷获取用户的联系人来做风控,所以...(大家忽略就好) 获取手机联系人很简单,就是查询android的数据库,用到的是ContentProvider进行跨进程通讯 ...