【问题标题】:Implementing ETag Support in ASP.NET MVC4 WebAPI在 ASP.NET MVC4 WebAPI 中实现 ETag 支持
【发布时间】:2015-12-15 06:25:55
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    就我个人而言,我不喜欢“框架魔法”,更喜欢 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 纯粹是对弱实体标记系统的说明。它还显示了所需的附加引号。

    【讨论】:

      【解决方案2】:

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


      更新

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


      更多更新

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

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

      【讨论】:

        【解决方案3】:

        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

        【讨论】:

          【解决方案4】:

          这似乎是您正在寻找的(请参阅“支持 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”属性添加到响应正文中。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-06-19
            • 2020-10-04
            • 2016-04-26
            • 2016-03-03
            • 1970-01-01
            • 2023-03-17
            • 1970-01-01
            • 2013-06-02
            相关资源
            最近更新 更多