在最新的ASP.NET MVC4测试版中,您如何通过ETag支持条件GET支持? ActionFilter需要能够完成为返回的资源生成ETag的请求,以便与请求中的If-None-Match标头进行比较。然后,无论If-None-Match标头中的传入ETag是否与生成的ETag相同,都将生成的ETag添加到ETag响应头。但是使用ASP.NET MVC4,我不知道从哪里开始。有什么建议吗?
答案 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”一节):
如果您的模型在域中存储得更深,并且您无法应用[ConcurrencyCheck]属性,则可以使用ODataModelBuilder执行此操作:
ODataModelBuilder builder = new ODataConventionModelBuilder();
var myEntity = builder.EntitySet<MyEntity>("MyEntities");
myEntity.EntityType.Property(l => l.Version).ConcurrencyToken = true;
这将使它将“@ odata.etag”属性添加到响应主体。