介绍

本文将介绍如何在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中的Controller

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

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

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

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

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

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

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

  5. ASP.NET Web API中使用OData

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

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

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

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

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

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

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

  9. 剖析Asp.Net Web API中HttpController的激活

    在Asp.Net Web API中,请求的目标是定义在某个HttpController中的某个Action方法.当请求经过Asp.Net Web API消息处理管道到达管道"龙尾" ...

随机推荐

  1. [转]Oracle字符串拼接的方法

    本文转自:http://www.blogjava.net/liuwuping12064915/archive/2011/06/27/353096.html 和其他数据库系统类似,Oracle字符串连接 ...

  2. CSS属性值一览

    牢记内联式>嵌入式(嵌入式中设置各种文字字体.大小.位置.颜色.外距.内距最好用选择器)>外部式(外联式)的使用 属性和属性值(点击可展开) font-family(字体) Microso ...

  3. Java基础知识强化之IO流笔记24:FileInputStream / FileOutputStream 复制文本文件案例2

    1. 需求:把d盘下的a.txt的内容复制到f盘下的b.txt中: 代码示例: package com.himi.filecopy; import java.io.FileInputStream; i ...

  4. Codeforces_776E: The Holmes Children (数论 欧拉函数)

    题目链接 先看题目中给的函数f(n)和g(n) 对于f(n),若自然数对(x,y)满足 x+y=n,且gcd(x,y)=1,则这样的数对对数为f(n) 证明f(n)=phi(n) 设有命题 对任意自然 ...

  5. git学习整理(1)git clone 理解

    1.git clone 的理解 git clone默认会把远程仓库整个给clone下来 ,只能clone远程库的master分支并在本地默认创建一个master分支 ,无法clone所有分支,若想要其 ...

  6. destoon分页

    <?php //控制分页//分页$pagesize=4;$pagesql="SELECT COUNT(*) AS num FROM `{$DT_PRE}` company"; ...

  7. rsync学习笔记

    转载地址:http://www.cnblogs.com/maxincai/p/5142245.html rsync同步工具 1.rsync介绍 rsync是一款开源的.快速的.多功能的.可实现全量及增 ...

  8. SQL查询中用到的函数

    数据库表  students      id name sex age address 101 张汉 男 14 杭州 102 欧阳钦 男 13 杭州 103 吴昊 男 14 北京 104 钱进进 男 ...

  9. PAT甲级1103 Integer Factorization【dfs】【剪枝】

    题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805364711604224 题意: 给定一个数n,要求从1~n中找 ...

  10. RocketMQ入门(生产者)_2

    从 RocketMQ环境搭建_1 我们已经建立了MQ的Server,接下来就是简单的生产和消费的过程. 1. rocketMQ的源码中有个示例代码example  ,我们从Apache官网中可以下载源 ...