17

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

4

4 回答 4

16

就个人而言,我不喜欢“框架魔法”,更喜欢 web 方法中的普通旧代码,否则我们最终会得到更类似于 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 纯粹是一个弱实体标记系统的说明。它还显示了所需的附加报价。

于 2012-07-04T15:27:37.797 回答
9

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


更新

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


更多更新

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

WebApiContrib 的 CachingHandler 仍将得到维护,因此如有任何错误或问题,请告诉我。

于 2012-05-04T13:21:02.133 回答
5

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

于 2015-12-14T22:25:55.120 回答
0

看来这就是您要寻找的内容(请参阅“支持 ETags”部分):

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”属性添加到响应正文中。

于 2014-09-27T18:14:16.380 回答