私は、単純にユーザーのリストを返すASP.Net Web APIコントローラーを持っています。HttpResponseMessageと共にアクションフィルターを使用してWeb APIでETagを使用する方法
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;
}
}
とのETagとキャッシュを管理する責任があるアクションフィルタ属性クラスEnableTag
:
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タグが作成され、後続の要求に対しては、ETagが存在するかどうかがチェックされます。その場合は、Not Modified
HTTPステータスが生成され、クライアントに戻ります。
私の問題は、ユーザーリストに変更があった場合、新しいETagを作成することです。新しいユーザーが追加されるか、既存のユーザーが削除されます。それに応答を追加します。これはuserList
変数によって追跡できます。
現在のところ、クライアントとサーバーから受信したETagは、2番目の要求ごとに同じです。この場合、実際には何も変更されていないときには常に、Not Modified
のステータスが生成されます。
誰でもこの方向に私を導くことができますか?前もって感謝します。
これは完璧です - それは、パフォーマンスの減少、応答をバッファリングすることなくWEBAPI通話用のETagソリューションを提供 - などのチェックサムソリューションが行います。 –