在ASP.NET MVC4 WebAPI中实现ETag支持

时间:2012-04-28 17:06:31

标签: asp.net-mvc-4 asp.net-web-api

在最新的ASP.NET MVC4测试版中,您如何通过ETag支持条件GET支持? ActionFilter需要能够完成为返回的资源生成ETag的请求,以便与请求中的If-None-Match标头进行比较。然后,无论If-None-Match标头中的传入ETag是否与生成的ETag相同,都将生成的ETag添加到ETag响应头。但是使用ASP.NET MVC4,我不知道从哪里开始。有什么建议吗?

4 个答案:

答案 0 :(得分:16)

就个人而言,我不是“框架魔术”的粉丝,更喜欢网络方法中的普通旧代码,否则我们最终会得到类似于WCF,yuk的东西。

因此,在Get Web方法中,手动创建响应如下:

var response = this.Request.CreateResponse(HttpStatusCode.OK, obj);
string hash = obj.ModifiedDate.GetHashCode().ToString();

response.Headers.ETag =
    new EntityTagHeaderValue(String.Concat("\"", hash, "\""), true);

return response;

请注意,从时间戳的哈希码生成的ETag纯粹说明了弱实体标记系统。它还显示了所需的额外报价。

答案 1 :(得分:9)

WebApiContrib中有一个ETagMessageHandler可以满足您的需求。


更新

我在WebApiContrib中实现了RFC 2616的服务器端缓存。寻找CachingHandler。 更多信息here


更新更新

这将在 CacheCow 下积极开发和扩展。这将包括客户端和服务器组件。即将发布的NuGet packages 现已发布。

WebApiContrib的CachingHandler仍然会被维护,所以任何错误或问题都请告诉我。

答案 2 :(得分:4)

Luke Puplett的回答让我走上正轨(+1),但请注意,您还必须阅读服务器端的ETag,以避免每次请求都发送所有数据:

string hash = obj.ModifiedDate.GetHashCode().ToString();
var etag = new EntityTagHeaderValue(String.Concat("\"", hash, "\""), true);

if (Request.Headers.IfNoneMatch.Any(h => h.Equals(etag)))
{
    return new HttpResponseMessage(HttpStatusCode.NotModified);
}

var response = this.Request.CreateResponse(HttpStatusCode.OK, obj);
response.Headers.ETag = etag;
return response;

尊重If-Modified-Since标题也是一个好主意。请参阅RFC 2616

答案 3 :(得分:0)

这似乎正是您所寻找的(请参阅“支持ETag”一节):

http://blogs.msdn.com/b/webdev/archive/2014/03/13/getting-started-with-asp-net-web-api-2-2-for-odata-v4-0.aspx

如果您的模型在域中存储得更深,并且您无法应用[ConcurrencyCheck]属性,则可以使用ODataModelBuilder执行此操作:

ODataModelBuilder builder = new ODataConventionModelBuilder();
var myEntity = builder.EntitySet<MyEntity>("MyEntities"); 
myEntity.EntityType.Property(l => l.Version).ConcurrencyToken = true;

这将使它将“@ odata.etag”属性添加到响应主体。