一个月前我问了几乎同样的问题。我的回答我描述了一个我的实现的例子。
在服务器端,我有在下列形式
GET /Service/RequestedData?param1=data1¶m2=data2…
GET /Service/RequestedData/IdOfData?param1=data1¶m2=data2…
PUT /Service/RequestedData/IdOfData // with param1=data1¶m2=data2… in body
POST /Service/RequestedData/IdOfData // with param1=data1¶m2=data2… in body
DELETE /Service/RequestedData/IdOfData
所以请求在休息一个接收请求WFC服务,但GET
请求有一些可选参数。特别是这部分是您感兴趣的端口。
因为WFC支持URL模板的功能,其中回复客户端请求的原型看起来像
[WebGet (UriTemplate = "RequestedData?param1={myParam1}¶m2={myParam2}",
ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
MyResult GetData (string myParam1, int myParam2);
像
GET /Service/RequestedData?param1=¶m2=data2
GET /Service/RequestedData?param2=data2¶m1=
GET /Service/RequestedData?param2=data2
所有的请求都将被映射到从侧面同一呼叫我的WCF服务。所以我少了一个问题。
现在,在每一个实施响应于HTTP请求GET
我在HTTP报头“缓存控制:最大年龄= 0”设置该方法的开始。这意味着客户端总是尝试验证客户端浏览器缓存,没有ajax
请求将不容易从本地缓存响应,就像它可以做Internet Explorer。
接下来我根据我的数据总是计算一个ETag
。确切的算法是一个单独讨论的主题,但重要的是,在HTTP标头中,对HTTP GET
请求的所有响应都存在ETag
。
因此,客户端每次验证他的本地缓存并发送GET请求到服务器。他们发送来自其本地缓存的ETag
,位于“If-None-Match
”HTTP标头内。服务器计算具有数据的ETag
,该数据将发送回此GET请求。它的数据的ETag
与客户端请求服务器发回的空主体和代码为“304 Not Modified
”的回应相同。在这种情况下,浏览器从本地缓存中提供数据。
如果从一个未知的原因,同一个客户端创建的URL请求的新版本,它将从Web浏览器解释为新 URL,那么Web浏览器将无法找到在本地缓存旧的服务器响应,并发送再向服务器请求相同的请求。这是一个真正的问题吗?服务器再次发送数据。如果你有一个服务器端缓存,你可以做更多的优化。在大多数情况下,GET请求的URL将由客户端JavaScript生成,因此您不会有这种情况。
的ETag
计算和“Cache-Control: max-age=0
”和Etag
头以及设置的设置“304 Not Modified
”的代码应该做的WFC服务,但它是很容易的。
最重要的是我的ETag
计算的实现并不像从数据库服务器和计算MD5高速缓存中获取整个数据那样广泛。我在SQL Server数据库的每一行数据中永久使用rowversion
数据类型。这rowversion
没什么别的作为数据库变化的计数器。如果其中一行数据rowversion
改变了相应行的值就会增加。因此,如果从rowversion
值的最大值开始SELECT
声明,并且此值与先前的请求相比没有变化,则可以确定数据在该时间段内未被更改。ETa
g的计算算法应该只对从表格中删除数据敏感。但这也是一个解决的问题。有关这方面的更多信息,请参阅Concurrency handling of Sql transactrion。
我不希望建议我的ETag
计算作为最佳选择,我只想说,计算ETag
可以便宜得多,因为从整个数据计算MD5。
出现错误时服务器抛出一个异常,该异常将映射到我在throw语句中定义的HTTP代码。作为一个主体WFC发送一个标准的JSON对象{"description":"My error text"}
。自定义错误对象也是可能的(见Is WebProtocolException included in .net 4.0?)。在客户端,我使用jQuery,并在错误事件处理程序中的相应的jQuery.ajax
错误消息将被解码并显示给用户。
所以我的推荐:对所有的HTTP GET
请求使用ETag
和“Cache-Control: max-age=0
”。对于所有其他请求,我会推荐您执行RESTfull服务。对于错误实现,您应该查看用于服务器和客户端实现的软件支持的最原始方式,并使用它。
UPDATED:要清除URL结构,我应该添加以下内容。在我的服务中,主要部分如GET /Service/RequestedData/IdOfData
描述了请求的数据对象。参数param1=data1¶m2=data2
主要对应于关于分类的信息,分页和过滤的数据。我为jQuery使用了主动的jqGrid插件,并且如果最终用户在网格中滚动到下一页,单击列标题(数据排序),或者如果他设置了关于搜索功能的过滤器,则所有这些遵循不同的可选参数附加了主要的URL。
共识似乎是用2.,我会这样。 – daxim 2010-05-09 09:21:58