【发布时间】:2013-11-22 12:39:03
【问题描述】:
我有一个简单地返回用户列表的 ASP.Net Web API 控制器。
public sealed class UserController : ApiController
{
[EnableTag]
public HttpResponseMessage Get()
{
var userList= this.RetrieveUserList(); // This will return list of users
this.responseMessage = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ObjectContent<List<UserViewModel>>(userList, new JsonMediaTypeFormatter())
};
return this.responseMessage;
}
}
还有一个动作过滤器属性类EnableTag负责管理ETag和缓存:
public class EnableTag : System.Web.Http.Filters.ActionFilterAttribute
{
private static ConcurrentDictionary<string, EntityTagHeaderValue> etags = new ConcurrentDictionary<string, EntityTagHeaderValue>();
public override void OnActionExecuting(HttpActionContext context)
{
if (context != null)
{
var request = context.Request;
if (request.Method == HttpMethod.Get)
{
var key = GetKey(request);
ICollection<EntityTagHeaderValue> etagsFromClient = request.Headers.IfNoneMatch;
if (etagsFromClient.Count > 0)
{
EntityTagHeaderValue etag = null;
if (etags.TryGetValue(key, out etag) && etagsFromClient.Any(t => t.Tag == etag.Tag))
{
context.Response = new HttpResponseMessage(HttpStatusCode.NotModified);
SetCacheControl(context.Response);
}
}
}
}
}
public override void OnActionExecuted(HttpActionExecutedContext context)
{
var request = context.Request;
var key = GetKey(request);
EntityTagHeaderValue etag;
if (!etags.TryGetValue(key, out etag) || request.Method == HttpMethod.Put || request.Method == HttpMethod.Post)
{
etag = new EntityTagHeaderValue("\"" + Guid.NewGuid().ToString() + "\"");
etags.AddOrUpdate(key, etag, (k, val) => etag);
}
context.Response.Headers.ETag = etag;
SetCacheControl(context.Response);
}
private static void SetCacheControl(HttpResponseMessage response)
{
response.Headers.CacheControl = new CacheControlHeaderValue()
{
MaxAge = TimeSpan.FromSeconds(60),
MustRevalidate = true,
Private = true
};
}
private static string GetKey(HttpRequestMessage request)
{
return request.RequestUri.ToString();
}
}
以上代码创建了一个属性类来管理ETag。因此,在第一个请求中,它将创建一个新的 E-Tag,对于后续请求,它将检查是否存在任何 ETag。如果是这样,它将生成Not Modified HTTP 状态并返回给客户端。
我的问题是,如果我的用户列表有变化,我想创建一个新的 ETag,例如。添加新用户或删除现有用户。并将其附加到响应中。这可以通过userList 变量进行跟踪。
目前,从客户端和服务器接收到的 ETag 在每秒请求中都是相同的,所以在这种情况下,它总是会生成Not Modified 状态,而我想要它实际上没有任何变化。
谁能指导我朝这个方向发展?
【问题讨论】:
标签: c# asp.net-web-api