介绍

本文将介绍如何在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中利用过滤器设置输出缓存的更多相关文章

  1. 利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理

    在Asp.net Web API中,对业务数据的分页查询处理是一个非常常见的接口,我们需要在查询条件对象中,定义好相应业务的查询参数,排序信息,请求记录数和每页大小信息等内容,根据这些查询信息,我们在 ...

  2. ASP.NET Web API中的Controller

    虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...

  3. 在ASP.NET Web API中使用OData

    http://www.alixixi.com/program/a/2015063094986.shtml 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在A ...

  4. 【ASP.NET Web API教程】4.3 ASP.NET Web API中的异常处理

    原文:[ASP.NET Web API教程]4.3 ASP.NET Web API中的异常处理 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...

  5. 【ASP.NET Web API教程】4.1 ASP.NET Web API中的路由

    原文:[ASP.NET Web API教程]4.1 ASP.NET Web API中的路由 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容. ...

  6. ASP.NET Web API中使用OData

    在ASP.NET Web API中使用OData 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在ASP.NET Web API中,对于CRUD(creat ...

  7. ASP.NET Web API中的JSON和XML序列化

    ASP.NET Web API中的JSON和XML序列化 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok ...

  8. 目标HttpController在ASP.NET Web API中是如何被激活的:目标HttpController的创建

    目标HttpController在ASP.NET Web API中是如何被激活的:目标HttpController的创建 通过上面的介绍我们知道利用HttpControllerSelector可以根据 ...

  9. 目标HttpController在ASP.NET Web API中是如何被激活的:目标HttpController的选择

    目标HttpController在ASP.NET Web API中是如何被激活的:目标HttpController的选择 ASP.NET Web API能够根据请求激活目标HttpController ...

随机推荐

  1. python 实现微信自动回复(自动聊天)

    原文地址(本人):https://blog.csdn.net/a5878989/article/details/54974249 介绍 微信自动回复其实主要就是登录,接收消息,回复消息三个功能,微信没 ...

  2. POJ2484

    A Funny Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6178   Accepted: 3861 Desc ...

  3. 一个优秀的SEOer必须掌握的三大标配技术

    首先,认识网页代码是基础 这里所讲的网页代码是指HTML代码,并不是指复杂的PHP模板技术.一般的培训机构总是提倡学SEO不用学网页代码,只要会购买域名空间搭建网站就行,因为现在的网站模板太丰富了,对 ...

  4. C# dev SearchLookUpEdit 和 RepositoryItemSearchLookUpEdit 测试

    一.searchLookUpEdit 绑定数据源 DataTable DtCompany = new DataTable();//数据源表,自己写数据. searchLookUpEditCus_no. ...

  5. 关于select 文字居向

    我们都知道select的文字默认居左,而如果你想改变它,用text-align是不起作用的,因为select没有这个样式 但是它有自己的样式属性 文字靠右对齐:direction: rtl; 而如果要 ...

  6. concrrent类下 BlockingDeque 下 自己实现代码编写

    一.LinkedBlockingDeque简介 java6增加了两种容器类型,Deque和BlockingDeque,它们分别对Queue和BlockingQueue进行了扩展. Deque是一个双端 ...

  7. Android为TV端助力 计算每个目录剩余空间丶总空间以及SD卡剩余空间

    ublic class MemorySpaceCheck { /** * 计算剩余空间 * @param path * @return */ public static String getAvail ...

  8. RHEL 5.7 使用rpm安装XtraBackup问题总结

    在Red Hat Enterprise Linux Server release 5.7 (Tikanga)上使用RPM方式安装Percona Xtrabackup 2.4.6时遇到了一些问题,特意总 ...

  9. iis 限制动态IP地址访问次数

    An IP Address Blocking HttpModule for ASP.NET in 9 minutes namespace YourModuleNameHere 10 { 11 publ ...

  10. web前端(8)—— CSS选择器

    选择器 选择器,说白了就是html的标签或者其相关特性,在一个HTML页面中会有很多很多的元素,不同的元素可能会有不同的样式,某些元素又需要设置相同的样式,选择器就是用来从HTML页面中查找特定元素的 ...