Wie zu verwenden ETag in Web-API über die Aktion filter zusammen mit HttpResponseMessage

Habe ich eine ASP.Net Web-API-controller, die einfach liefert die Liste der Benutzer.

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;
       }
}

und eine Aktion filter-Attribut class EnableTag die dafür verantwortlich ist, zu verwalten ETag und cache :

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();
    }
}

Den oben genannten code, erstellen Sie ein Attribut Klasse zur Verwaltung von ETag. Also auf die erste Anforderung, wird eine neue E-Tag und für die nachfolgende Anforderung es wird geprüft, ob jede ETag existierte. wenn dem so ist, wird es erzeugt Not Modified HTTP-Status und wieder zurück zum client.

Mein problem ist, ich möchte erstellen Sie eine neue ETag wenn es Veränderungen in meinem Benutzer-Liste, ex. ein neuer Benutzer Hinzugefügt oder ein vorhandener Benutzer gelöscht wird. und hängen Sie es mit der Antwort. Dieser kann nachverfolgt werden durch die userList variable.

Derzeit ist die ETag empfangen von client und server sind die gleichen, die aus jeder 2. Anfrage, so dass in diesem Fall es wird immer generieren Not Modified status, während ich will es, wenn sich eigentlich nichts geändert.

Kann jemand mich führen, in diese Richtung? Vielen Dank im Voraus.

InformationsquelleAutor SoftSan | 2013-11-22
Schreibe einen Kommentar