title: How to use ETag in Web API using action filter along with HttpResponseMessage
body: <p>I have a ASP.Net Web API controller which simply returns the list of users.</p>
  
  <pre><code>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&lt;List&lt;UserViewModel&gt;&gt;(userList, new  JsonMediaTypeFormatter())
          };
          return this.responseMessage;
         }
  }
  </code></pre>
  
  <p>and an action filter attribute class <code>EnableTag</code> which is responsible to manage ETag and cache:</p>
  
  <pre><code>public class EnableTag : System.Web.Http.Filters.ActionFilterAttribute
  {
      private static ConcurrentDictionary&lt;string, EntityTagHeaderValue&gt; etags = new ConcurrentDictionary&lt;string, EntityTagHeaderValue&gt;();
  
      public override void OnActionExecuting(HttpActionContext context)
      {
          if (context != null)
          {
              var request = context.Request;
              if (request.Method == HttpMethod.Get)
              {
                  var key = GetKey(request);
                  ICollection&lt;EntityTagHeaderValue&gt; etagsFromClient = request.Headers.IfNoneMatch;
  
                  if (etagsFromClient.Count &gt; 0)
                  {
                      EntityTagHeaderValue etag = null;
                      if (etags.TryGetValue(key, out etag) &amp;&amp; etagsFromClient.Any(t =&gt; 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) =&gt; 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();
      }
  }
  </code></pre>
  
  <p>The above code create an attribute class to manage ETag. So on the first request, it will create a new E-Tag and for the subsequent request it will check whether any ETag is existed. If so, it will generate <code>Not Modified</code> HTTP Status and return back to client. </p>
  
  <p>My problem is, I want to create a new ETag if there are changes in my user list, ex. a new user is added, or an existing user is deleted. and append it with the response.  This can be tracked by the <code>userList</code> variable.</p>
  
  <p>Currently, the ETag received from client and server are same from every second request, so in this case it will always generate <code>Not Modified</code> status, while I want it when actually nothing changed. </p>
  
  <p>Can anyone guide me in this direction?</p>