数据点

创建和使用 JSON 格式 OData

Julie Lerman

下载代码示例

Julie Lerman在我 6 月的专栏中,"数据绑定 OData 在 Web 应用程序与 Knockout.js"(msdn.microsoft.com/magazine/jj133816),我有一些有趣的 Knockout.js 和 OData。因为我学到了如何数据绑定到挖空的 OData 服务,结果我还发现了更多关于 OData 和 JSON 比知道以前。在本月的专栏中,我将我重点转移到消费从 OData JSON 和创建 JSON 友好 WCF 的数据服务。

我会展示如何使用直接从 JavaScript JSON、 如何利用 OData JavaScript SDK (称为 datajs) 以及如何确保您的 feed 是足够灵活,可以支持的客户端的编码将需要 JSON 的任何样式。

OData 是一个规范,确保数据服务消费者可以依靠一致的体验,从他们消费的服务。规范的规则之一是 OData 的结果是 ATOM 格式 (这是以特定的方式格式化的 xml),默认情况下输出,它还可以输出 JSON 格式的结果。

随着 OData 规范的发展,它引入了新的功能,您可能要使用您的服务的用户可以利用。我讨论的各种方式消耗并创建 JSON OData 饲料中后,我会请确保您了解如何即将到来的变化,OData 规格将影响 OData 和你可以今天做准备。首先将通过公开下面的架构在我服务的客户:

public class Customer
{
  public int Id { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string AccountNumber { get; set; }
}

默认情况下,从我的服务的客户结果将原子数据并看 (如通过浏览器来格式化),如中所示图 1

Results as ATOM
图 1 结果作为原子

输出 JSON 将相同的结果:

{"d":[
{"__metadata":{"id":"http://localhost:43447/DataService.svc/Customers(1)",
               "uri":"http://localhost:43447/DataService.svc/Customers(1)",
               "type":"DataAccessMSDNJuly2012.Customer"},
  "Id":1,
  "FirstName":"Julie",
  "LastName":"Lerman",
  "AccountNumber":"A123"}
]}

如果您正在使用的原始的原子或 JSON 结果,输出的格式可以将大不相同的编码的易用性。 例如,如果你正在吃饲料的 JavaScript,容易得多,直接使用 JSON 对象,而不愿解析 XML。

有两种方法,以确保您的结果回来 JSON 格式:您可以指定应用程序/json 请求标头中,或您可以添加一个 OData 的查询参数。 构成小提琴手中的请求,以测试,时可以非常轻松地添加标头,如中所示, 图 2

Specifying JSON in the Request Header
图 2 指定请求标头中的 JSON

您构建您的请求,但你不必感谢几个其他选项,请转到该长度时,还可以在 JQuery 添加标头。 这些选项中的一个是使用 datajs,OData,它提供许多其他好处以及针对 OData 编码的 JavaScript 库。 另一个选项是使用 OData 查询参数,$格式。

默认情况下的 JSON 跟 datajs

您可以下载从 datajs datajs.codeplex.com。 写作时,当前版本是 1.0.3。

如果您正在使用 Visual Studio,你可以直接向您的项目使用的 NuGet 软件包管理器添加 datajs。 NuGet 将向项目中添加脚本的文件夹,并将当前版本的 datajs (datajs 1.0.3.js) 和其相关的小脚本文件放在该文件夹中。

脚本库提供一类称为 OData,轻松地从 OData 兼容的饲料,读取和写入,并提供其他功能。 虽然很容易可以将一个标头插入通过 OData.read 函数的请求,但它没有必要。 默认情况下,datajs 将自动添加标头因为如果您正在使用此库,它很可能你想 JSON。

这里是一些 JavaScript 调用 OData.read,通过在 Uri,表示我的数据服务的查询,并指定如何处理结果中将 (在这种情况下,我感到结果存储在一个变量中命名为客户):

<script src="Scripts/datajs-1.0.2.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
  var customer;
  OData.read({ requestUri:"http://localhost:43447/DataService.svc/Customers?$top=1"
             },
             function (data, response) {
               customer = data.results[0];
             },
             function (err) {
               alert("Error occurred: " + err.message);
             });
</script>

通过此脚本调试,我可以看到查询的结果是一个对象,如中所示图 3

Debug View of JSON Result
图 3 调试 JSON 结果的视图

运行要捕获的 HTTP 通信量的小提琴手,我可以看到接受标头,指定应用程序/json,是该请求的一部分。

如果你是一个 PHP 开发者,您应该检查相关的库中,php OData SDK (odataphp.codeplex.com)。 就像 datajs 图书馆一样 JavaScript 开发者,可以确保 PHP SDK,结果是有关。 但在这种情况下,它会请求 ATOM 格式,然后到 PHP 对象实现的结果的原子数据。

请求 JSON 与 $格式参数

并非每个人都需要 JSON 将使用 datajs 图书馆。 但这并不意味着您必须使用请求标头的 JSON 问。 OData 规范还具有查询参数,$格式,接受 json 作为其值中的一个。

这里是直接请求 JSON 的修改的 Uri:

http://localhost:43447/DataService.svc/Customers (1) 吗?$ 格式 = json

您可以向任何查询添加 $格式参数。 在这里我我与筛选器相结合的格式要求:

http://localhost:43447/DataService.svc/Customers?$filter=FirstName eq '朱莉' &$ 格式 = json

强制数据服务来纪念 $格式参数

虽然使用此格式参数来请求 JSON 是 OData 规范的一部分,不是每个数据服务将知道如何处理参数。 事实上,当您创建.net WCF 数据服务,它将返回原子默认。 于是,当服务将接受 $格式 = json 参数,它仍将在响应中返回原子。 OData 团队的一些开发商已共享一个简单的解决方案,但是 (可在 archive.msdn.microsoft.com/DataServicesJSONP) 您可以添加到您的应用程序启用 WCF 数据服务,以处理 $格式命令和返回 JSON。

扩展是表格内所提供的一个名为 JSONPSupportInspector 类和属性名,JSONP­SupportBehavior。 这两个类利用逻辑从 System.Component­模型。 你可以直接向您的项目中添加类,或从它们引用创建程序集。 一旦您 WCF 数据服务有权访问这些类,您需要做的一切是将 JSONPSupportBehavior 属性添加到服务类,如下所示:

[JSONPSupportBehavior]
public class DataService : DataService<SalesContext>
{
  public static void InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("Customers", EntitySetRights.All);
    config.SetEntitySetAccessRule("Orders", EntitySetRights.All);
  }

使用此属性中的地方,我的服务会响应 $格式时将其添加到查询中,并且我的服务将返回 JSON = json 参数。

我写此列在 2012 年 4 释放的 WCF 数据服务 5 仍然要求您显式添加 JSONP 的支持为您的数据服务的高跟鞋。 如果您想要看到这个包裹到 WCF 数据服务 API 在将来,您可以添加到团队的让人心动功能建议在表决 bit.ly/ImeTQt

JSON 支持和 OData 版本

OData 规范目前在第 2 版和不断发展的。 第三版的工作已经展开,beta 已经发售 OData.org。 默认情况下,您的 WCF 数据服务将目标版本 1。 不幸的是,默认设置不起作用如果您想要使用的 OData 版本 2 功能,如服务器端分页,WCF 数据服务中可用的。 我已经添加到我的服务表现出的 SetEntitySetPageSize 配置:

public static void InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("Customers", EntitySetRights.All);
    config.SetEntitySetAccessRule("Orders", EntitySetRights.All);
    config.SetEntitySetPageSize("Customers", 3);
  }

使用此版本 2 功能到位,服务将引发异常,并告诉您您必须指定 MaxProtocolVersion 大于第 1 版。 这里是与 SetEntitySetPageSize 配置关联的错误:

"不能是服务器端分页时所使用的 MaxProtocol­版本的数据服务设置为 DataServiceProtocolVersion.V1。"

若要更正此问题,它很容易将服务代码中设置的版本:

public static void InitializeService(DataSeviceConfiguration config)
  {
    config.SetEntitySetAccessRule("Customers", EntitySetRights.All);
    config.SetEntitySetAccessRule("Orders", EntitySetRights.All);
    config.SetEntitySetPageSize("Customers", 3);
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
  }

而且,在这种情况下,它是仍有可能要求 JSON 输出在请求标头或在 Uri 中使用 $格式参数。

但是,您可能想要设计您的服务要向前兼容,将 MaxProtocolVersion 设置为 DataServiceProtocol­Version.V3。 但在版本 3,JSON 格式将更改为更精简的输出格式,称为 JSON 光 (bit.ly/JrM6RQ)。 如果您的客户端应用程序不期望的精简的 JSON 格式,这可以是一个大问题。 从消费应用程序的角度来看,它将出现 JSON 的请求已被忽略,因为原子,将返回与不 JSON。

这是因为您的客户端必须显式请求的更详细的格式或指定的 OData 版本的目标。 不满意这些规则之一,该服务将返回原子。 因此,你必须做一个或另一方所需任务,得到 JSON 的结果,当该服务被设置为版本 3。

下面是修改,以明确要求详细的 JSON 格式的请求标头:

接受:应用程序/json ; odata = 详细

并与 OData 响应使用版本 2 的格式特定请求标头的示例如下:

接受:应用程序/json

MaxDataServiceVersion: 2.0

如果您正在使用 $格式 = 在查询中而不是请求标头中的 JSON json 参数吗? 同样,该服务不会理解该请求,你就会声明的 MIME 类型不受支持的错误。 在这种情况下,您必须在您的请求标头中包括 MaxDataServiceVersion。

但是,如果您正在使用 datajs,您不需要担心。 从 1.0.3 版开始,图书馆是意识到需要的版本信息,并提供它在其请求中。 在这个地方,你的服务已准备好 OData 版本 3 和消费者具有灵活性,要求他们喜欢哪种版本的格式。

OData 管道 JSON

由于其流线型的格式 JSON 是开发商越来越重要格式。 您可能还记得甚至包括一些新的文档数据库中写过 2011 年 11 月的数据点列中,"什么到底是文献数据库吗?"(msdn.microsoft.com/magazine/hh547103)、 上 JSON 使用 JSON 或一些扭曲的存储数据。

如果您签出最后一个月的数据点的列,您可以找到的读取和写入数据服务使用 JSON 和 Knockout.js 的例子。

随着我们进入更多和更多的应用程序断开连接时的年龄,你就会欣赏消耗 JSON 作为 OData 的能力 (中任意一种详细或以更有效率的新格式)。 如果您正在创建服务,你的消费者肯定会感激如果你可以很容易为他们以这种方式访问您的数据。

Julie Lerman 是 Microsoft MVP,.net 的导师和顾问住在佛蒙特州的丘陵。您可以找到她介绍数据访问和用户组和世界各地的会议其他 Microsoft.net 主题。在她博客 thedatafarm.com/blog 是作者的"编程实体框架"(O'Reilly 媒体,2010年) 和"编程实体框架:代码第一次"(O'Reilly 媒体,2011年)。跟她在 Twitter 上 twitter.com/julielerman

由于下面的技术专家,检讨这篇文章:Alejandro Trigo