设为首页 收藏本站
查看: 1675|回复: 1

[经验分享] PartitionKey 与 RowKey 含有 ‘%’ 字符会导致Windows Azure Tables API出错

[复制链接]

尚未签到

发表于 2016-5-24 11:33:35 | 显示全部楼层 |阅读模式
  问题表现
  我们发现当PartitionKey或RowKey含有“%”字符时,应用Windows Azure Tables的服务将受到影响。
  受此影响的API包括:Get entity, Merge entity, Update entity, Delete entity, Insert或Merge Entity,以及Insert或Replace Entity的API。如果任何上述API被调用时其PartitionKey或RowKey含有“%”,用户则将收到404 Not Found或者400 Bad Request的错误代码。此外,当用户调用Insert或Merge Entity以及Insert或Replace的API时,请求可能成功但所储存的字符串可能并不正确。
  注意Insert Entity, Entity Group Transaction以及Query Entities的API不受影响,因为PartitionKey和RowKey并不是其URL路径的一部分。
  根本原因
  Windows Azure Table服务处理请求时会对URL路径部分重复解码,此时会错误地理解此含有“%”的字符串。注意URL的查询字符串部分以及HTTP正文部分中的字符串并不受此影响。所以,一个查询中任何其它的属性过滤器将不受影响 – 仅PartitionKey及RowKey受影响。
  以下是此问题如何发生的一个例子:插入一个实体并使PartitionKey = “Metric%25” 和RowKey = “Count”的操作将会成功。因为PartitionKey, RowKey和自定义值是请求负载的一部分而并非URL路径部分。现在,当你试图取回这个已经存在的实体之时,Get Entity HTTP URL将会如下所示:
  http://foo.table.core.windows.net/Metrics(PartitionKey='Metric%2525',RowKey='Count')
  然而由于二次解码的错误,PartitionKey将会在服务器端被翻译成“Metric%”,这与原值不同。在这种情况下,404 Not Found错误将会被返回。
  解决方法
  如果你尚未在任何实体中使用含“%”的PartitionKey或RowKey,我们建议您做如下两件事:


  • 避免在PartitionKey和RowKey中用到“%”,或将其替换为其它字符如“-”。
  • 考虑在PartitionKey和RowKey中应用URL 安全64位编码。
  注意:请不要将重复为PartitionKey和RowKey值编码作为解决方法,以免与将来Windows Azure Tables含有服务器端修正的发布不兼容。
  如果你已经插入了含有“%”的PartitionKey或RowKey的实体,我们建议如下解决方案:


  • 对于Get Entity:


  • 用Entity Group Transaction并使用一个内部的GET Entity命令。(详见下节示例)
  • 在调用Query Entities API试图取回一个单一实体时依赖$Filter变量。尽管此方法不适用于Windows Azure Storage 客户端库或WCF Data Services 客户端库的用户,它适用于对传输协议有控制权的用户。举例来说,对于以上“根本原因”一节中所提到的同一个实体可以考虑如下的查询URL语法:
  http://foo.table.core.windows.net/Metrics()?$filter=(PartitionKey%20eq%20'Metric%2525')%20and%20(RowKey%20eq%20'Count')


  • 对于Update Entity, Merge Entity, Delete Entity, Insert或Merge Entity,以及Insert或Replace Entity的API,请使用Entity Group Transaction以及你想执行的内部操作。(详见下节示例)
  Windows Storage Client库的解决方案示例
  假设用户已经插入了含有PartitionKey = “Metric%25” 及 RowKey = “Count”的实体。以下代码展示了如何利用Windows Azure Storage Client库以取出和更新实体。这段代码应用了前文提到的Entity Group Transaction的解决方案。请注意Get Entity和Update Entity操作都被作为批量操作执行。
  

// 创建表的服务上下文
TableServiceContext tableServiceContext = new TableServiceContext(tableClient.BaseUri.ToString(), tableClient.Credentials);
// 建立单点查询
DataServiceQuery<MetricEntity> getEntityQuery = (DataServiceQuery<MetricEntity>)
from entity in tableServiceContext.CreateQuery<MetricEntity>(customersTableName)
where entity.PartitionKey == "Metric%25" && entity.RowKey == "Count"
select entity;
// 建立entity group transaction并使用内部Get Entity的请求
DataServiceResponse batchResponse = tableServiceContext.ExecuteBatch(getEntityQuery);
// 这是批量操作唯一的应答
QueryOperationResponse response = (QueryOperationResponse) batchResponse.First();
if (response.StatusCode == (int) HttpStatusCode.OK)
{
IEnumerator queryResponse = response.GetEnumerator();
queryResponse.MoveNext();
// 读取这个单独的实体
MetricEntity  singleEntity = (MetricEntity)queryResponse.Current;
// 更新实体
singleEntity.MetricValue = 100;
tableServiceContext.UpdateObject(singleEntity);
// 确定使用批量操作选项储存
tableServiceContext.SaveChanges(SaveChangesOptions.Batch);
}

  


Java Storage Client解决方案代码示例
  介于上述问题与服务有关,同样的行为也会在用Storage Client的Java库执行单实体操作时发生。然而,也可以同样应用Entity Group Transaction来解决此问题。最新版本的可以被用于实现前述解决方案的库可以在此找到here。

// 定义批量操作
TableBatchOperation batchOperation = new TableBatchOperation();
// 取回实体
batchOperation.retrieve("Metric%25", "Count", MetricEntity.class);
// 提交一个操作到表服务
tableClient.execute("foo", batchOperation);
更多关于用Java Storage Client处理表格的信息请详见:
  http://blogs.msdn.com/b/windowsazurestorage/archive/2012/03/05/windows-azure-storage-client-for-java-tables-deep-dive.aspx
  长期修正
  我们将把这个修正作为下一个版本更新的一部分进行发布。我们介时将更新此帖以反映其针对的版本信息。
  我们对为您带来的不便表示深深道歉!
  Jean Ghanem
  本文翻译自:http://blogs.msdn.com/b/windowsazurestorage/archive/2012/05/28/partitionkey-or-rowkey-containing-the-percent-character-causes-some-windows-azure-tables-apis-to-fail.aspx

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-221161-1-1.html 上篇帖子: 宣布: Windows Azure SQL 数据库的的新系统视图 下篇帖子: 现实世界的Windows Azure:采访AppPoint的技术总监Rajesekar Shanmugam
累计签到:32 天
连续签到:1 天
发表于 2016-5-24 12:17:21 | 显示全部楼层
学习学习了

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表