此主题尚未评级 - 评价此主题

针对 Windows Azure 中的 OData 的指导

作者: Glenn Gailey

审校:Abhiram Chivukula

本文总结了当前 OData 在 Windows Azure 平台中的使用情况。它还提供有关创建、部署和使用在 Windows Azure 中托管的 OData 服务的指南。

本主题包含以下各指南章节:

本文假定您熟悉 WCF Data Services 和 ADO.NET 实体框架。有关这些 .NET Framework 技术的详细信息,请参阅 WCF Data ServicesADO.NET Entity Framework

概述:云中的 OData

开放数据协议 (OData) 是基于表征状态传输 (REST) 的协议。创建基于云的数据服务时,您的数据可以被支持 HTTP 消息传送、可以处理 XML 或 JSON 的任意客户端使用。OData 将数据作为可按 URI 寻址的资源公开。可以使用 GET、PUT、POST 和 DELETE 的标准 HTTP 动词访问和更改数据。OData 使用实体数据模型的实体-关系约定来将资源作为一组按关联相关的实体公开。

由于它基于 Internet 标准,在云中创建基于 REST 的数据服务时选择 OData 也就不足为奇了,这些数据服务可被各种可识别 Internet 的客户端平台和设备使用。因此,OData 由 Windows Azure 平台的很多功能使用,包括:

Windows Azure 存储表服务
用于访问 Windows Azure 表服务的编程接口是 OData。您可以通过手动编写 HTTP 请求访问表服务。有关详细信息,请参阅Table Service REST API。您还可以使用 OData 客户端(如 Windows Azure 存储客户端或 WCF Data Services 客户端)来访问表服务。有关详细信息,请参阅Using the .NET Client Library with the Table Service

Windows Azure Marketplace
Windows Azure Marketplace 是简化从各种源发布和使用数据的基于订阅的信息和应用程序市场。Marketplace 将数据作为 OData 源发布以便可以轻松在您的可识别 OData 的应用程序中使用它。有关详细信息,请参阅 Windows Azure Marketplace

ACS 管理服务
Windows Azure 访问控制服务 (ACS) 2.0 为 ACS 管理服务提供基于 OData 的 API。有关详细信息,请参阅 ACS Management Service API Reference

您还可以在 Windows Azure 上创建和部署自己的 OData 服务。在这种情况下,数据服务是由 ASP.NET Web 角色托管的、基于 .NET Framework 的 Web 应用程序。使用以下功能和工具包可以在 Windows Azure 上创建和部署 OData 服务:

WCF Data Services
WCF Data Services 是用于创建实现 OData 的数据服务应用程序的一个 .NET Framework 组件。有关详细信息,请参阅 WCF Data Services。WCF Data Services 允许您创建作为 ASP.NET Web 角色托管的、基于 Windows Azure 的自定义数据服务。使用 WCF Data Services,您可以公开来自各种 Windows Azure 源的数据,包括 SQL Database 和 Windows Azure Blob 存储区。您用于定义数据服务的数据模型的数据服务提供程序依赖于数据源。有关详细信息,请参阅Data Services Providers (WCF Data Services)

Windows Azure Tools for Visual Studio 包含一组集成的工具用于在 Visual Studio 中开发基于 Windows Azure 的数据服务。有关如何使用 Visual Studio 工具来创建和部署数据服务以公开 SQL 数据库的 OData 源的示例,请参阅文章云中的数据服务。有关使用 WCF Data Services 创建和部署 OData 服务的一般指南,请参阅Defining WCF Data Services

Sync Framework 工具包
Sync Framework 工具包扩展了 Microsoft Sync Framework 的功能,允许您创建基于 WCF Data Services 的同步服务,该服务可以在 Windows Azure 上部署。通过这个专用 OData 服务,您可以在 SQL 数据库和可以使用 OData 源的各种客户端应用程序和设备之间同步数据。有关详细信息,请参阅 MSDN 代码库中的 Microsoft Sync Framework 工具包项目页

有关 OData 协议的更一般信息,包括 OData 生成者和使用者的列表以及支持 OData 的客户端库的列表,请访问 OData.org 网站

使用实体框架提供程序连接到 SQL Database 的指南

您可以使用 WCF Data Services 中的实体框架提供程序来创建将 SQL Database 数据作为 OData 源发布的数据服务。有关示例,请参阅How to: Connect to Windows Azure SQL Database Through WCF Data Services。当您使用实体框架提供程序来定义数据服务的数据模型时,WCF Data Services 使用提供的类(从 ObjectContext 继承)来编写和执行针对数据库的查询。有关详细信息,请参阅Entity Framework Provider (WCF Data Services)

使用实体框架提供程序以允许 WCF Data Services 从 SQL 数据库发布数据时,遵循以下规则。

使用实体框架 Code First 提供程序

ADO.NET 实体框架允许使用设计器 (Model First)、通过映射到现有数据库 (Database First) 以及使用您自己的公共语言运行时 (CLR) 对象 (Code First) 来定义数据模型。有关详细信息,请参阅Creating and Mapping a Conceptual Model (Entity Framework)。Code First 是在 Entity Framework 4.1 中引入的。与 Model First 方法类似,Code First 允许您在没有现有 SQL 数据库的情况下定义一个数据模型。Code First 自动在针对的 SQL Database 服务器中生成一个新的 SQL 数据库。教程使用 Code First 和 Windows Azure SQL Database 开发 Windows Azure 数据应用程序说明如何为 SQL 数据库创建 Code First 数据模型。

使用 Code First 定义数据模型时,您定义一个从 DbContext 而非 ObjectContext 继承的上下文类。但是,将实体框架提供程序与 WCF Data Services 一起使用时,DataService 类必须属于从 ObjectContext 继承的类型。有一个解决方法允许您将 Code First 数据模型与 WCF Data Services 一起使用。您必须覆盖 CreateDataSource 来显式为数据服务运行时提供基础 ObjectContext。有关如何执行此操作的示例,请参阅文章将 Entity Framework 4.1 Code First 与 WCF Data Services 一起使用

解决 SQL Database 连接失败问题

当您使用实体框架访问 SQL Database 中的数据时,我们建议您尝试解决连接失败问题。如文章 Windows Azure SQL Database 和实体框架连接失败处理中所述,在使用实体框架时,有几种方法可以解决 SQL Database 连接失败问题。当前在实体框架或 WCF Data Services 中不提供自动重试机制。使用实体框架提供程序时,WCF Data Services 为您管理 ObjectContext。这意味着没有办法将重试逻辑注入各个实体框架操作。因此,您必须实现重试逻辑以清除可能在执行期间导致失败的所有无效连接的连接池。

您具有 Model First 或 Database First 模型时

当您使用实体框架工具创建 Model First 或 Database First 数据模型时,这些工具生成一个强类型化的 ObjectContext 作为分部类。此分部类包含一个分部 OnContextCreated 方法。

要解决连接失败问题,请在您的数据服务项目的单独代码页中实现以下方法:

partial void OnContextCreated()
{
    int MaxRetries = 10; 
    int DelayMS = 100; 
    RetryPolicy policy = 
        new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(
            MaxRetries, TimeSpan.FromMilliseconds(DelayMS)); 

    // Invoke the query in an inline delegate using the lambda operator.
    policy.ExecuteAction(() =>
    {
        try
        {
            // Try to open the connection.
            Connection.Open();
            var storeConnection = 
            (SqlConnection)((EntityConnection)Connection)
            .StoreConnection;

            // Send a quick query to the SQL database to test the connection.
            new SqlCommand("declare @i int", storeConnection).ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            // If we fail, close the connection.
            Connection.Close(); 
            throw ex;
         }
      });
}

当创建上下文来将开销不大的查询发送到 SQL Database 以清除连接池时,此方法引入重试逻辑。重试逻辑由暂时性故障处理应用程序块中的 RetryPolicy 类提供,该块随 Windows Azure 的 Enterprise Library 5.0 集成包 — 2011 年 11 月一起发布。此应用程序块还作为 Nuget 包提供。上一个代码示例需要以下 using 语句:

using Microsoft.Practices.EnterpriseLibrary.WindowsAzure.TransientFaultHandling.SqlAzure;
using Microsoft.Practices.TransientFaultHandling;
using System.Data.EntityClient;
using System.Data.SqlClient;

您具有 Code First 模型时

当您使用 Code First 定义实体框架数据模型时,必须覆盖 CreateDataSource 以显式将基础 ObjectContext 提供给数据服务运行时。有关详细信息,请参阅将 Entity Framework 4.1 Code First 与 WCF Data Services 一起使用。对于基于 Code First 数据模型的数据服务,您在覆盖 CreateDataSource 方法的方法中执行相似的重试操作。以下是针对基于 Northwind 的 Code First 数据模型的方法覆盖:

// You must override CreateDataSource to manually return an ObjectContext,
// otherwise the runtime tries to use the built-in reflection provider instead of 
// the Entity Framework provider.
protected override ObjectContext CreateDataSource()
{
    // Create a new Code First Northwind DbContext.
    NorthwindContext nw = new NorthwindContext();
    nw.Configuration.ProxyCreationEnabled = false;
    
    // Define a retry policy for our query to the SQL database.
    int MaxRetries = 10;
    int DelayMS = 100;
    RetryPolicy policy =
        new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(
            MaxRetries, TimeSpan.FromMilliseconds(DelayMS));

    
    // Invoke the query in an inline delegate using the lambda operator.
    policy.ExecuteAction(() =>
    {
        try
        {
            // Try to open the connection.
            nw.Database.Connection.Open();
            var storeConnection = (SqlConnection)(nw.Database.Connection);

            // Send a quick query to the SQL database to test the connection.
            new SqlCommand("declare @i int", storeConnection).ExecuteNonQuery(); 
        }
        catch (Exception ex)
        {
            // If we fail, close the connection.
            nw.Database.Connection.Close();
            throw ex;
         }
    });

    // Configure DbContext before we provide it to the 
    // data services runtime.
    nw.Configuration.ValidateOnSaveEnabled = false;

    // Get the underlying ObjectContext for the DbContext.
    var context = ((IObjectContextAdapter)nw).ObjectContext;

    // Return the underlying context.
    return context;
}

与以前的示例一样,此代码使用暂时性故障处理应用程序块中的 RetryPolicy 类。

利用 Blob 存储区

OData 服务可以公开二进制大型对象 (BLOB) 数据。开放数据协议 (OData) 定义检索独立于其所属实体的二进制数据的机制。这通过将二进制数据与单独数据流中的实体分隔而实现。使用 WCF Data Services,您通过实现 IDataServiceStreamProvider 接口以定义流式数据提供程序来定义二进制资源流。该流式提供程序实现为数据服务提供与作为 Stream 对象或用于访问二进制数据的 URI 的特定实体关联的流。有关详细信息,请参阅Streaming Provider (WCF Data Services)

为 Windows Azure 中托管的数据服务创建流式数据服务提供程序时,在实现 GetWriteStreamGetReadStream 时使用 Windows Azure Blob 服务。为了获得最佳性能,您的 GetReadStreamUri 实现应返回 Blob 的 URI 以便客户端可以直接从 Blob 服务请求它。

保护 OData 服务

有一些情形适合发布允许匿名访问的基于 Windows Azure 的 OData 服务。但是,在很多情况下,您必须确定谁在访问数据服务。“谁”的对应安全术语为“主体”。您还必须确定指定的主体是否可以访问资源,并可能根据发出请求的主体筛选查询结果。您还需要保护数据服务返回的数据以防止泄露给第三方。有关保护 WCF Data Services 的一般信息,请参阅Securing WCF Data Services

身份验证
WCF Data Services 不执行客户端请求的身份验证。它依赖托管平台来执行身份验证并为其提供有关发出请求的主体的信息。当您为 Windows Azure 中托管的数据服务实施身份验证时,应使用 OAuth 2.0 身份验证。在 Windows Azure 平台中,对此身份验证方案的支持由访问控制服务 (ACS) 提供。有关如何使用 ACS 为您的数据服务实施 OAuth 2.0 身份验证的示例,请参阅文章 OData 和 OAuth - 使用 OAuth 2.0 保护 OData 服务

有关如何使用 OAuth 2.0 连接到 OData 服务的示例,请参阅文章连接到受 OAuth 2.0 保护的 OData 服务

授权
我们建议您定义一些规则,这些规则将对数据模型资源的访问限制为支持客户端应用程序所需的最低特权集。有关详细信息,请参阅Configuring the Data Service (WCF Data Services)。客户端经过身份验证后,可以从主体的标识获取诸如用户名之类的信息。根据数据模型,在数据服务将数据返回客户端前,此客户端特定的信息可用于筛选数据。您可以通过定义必须筛选的特定实体集的查询拦截器来这样做。有关详细信息,请参阅Interceptors (WCF Data Services)

通过定义仅返回属于特定主体或角色的数据的查询拦截器,WCF Data Services 可以支持多租户应用程序。在多租户模型中,在保持数据隔离时单个数据服务可以为多个客户端提供服务。有关创建基于 Windows Azure 的多租户应用程序的更多指南,请参阅在 Windows Azure 上设计多租户应用程序。您还可以定义更改拦截器以在将更改发送到数据服务时注入业务逻辑。此逻辑还可以检查经过身份验证的请求的主体,并可能回滚未经授权执行更改的用户所做的更改。

不推荐重新发布表服务

用于访问 Windows Azure 表服务的 TableServiceContext 类基于 WCF Data Services 客户端。可以通过将反射提供程序用于 TableServiceContext 来重新发布表服务 OData 源。但是,WCF Data Services 客户端库不支持 OData 服务使用的语言集成查询 (LINQ) 查询的完整集合。因此,不推荐您使用 WCF Data Services 重新发布表服务。

增强 WCF Data Services 应用程序的指南

本节包含有关 Windows Azure 中托管的 WCF Data Services 的另一指南。您可以使用此指南来改进访问 OData 服务的客户端的体验。

定义大型实体集的页限制
当您使用 WCF Data Services 公开大型数据集时,应设置页限制以限制单个查询中返回给客户端的实体数。如果不进行页限制,几个客户端就可以通过针对包含很多实体的源发出简单请求来轻松占用过多资源。页限制的作用是将大型查询拆分为较小的几部分,这将减小大型查询对系统总体响应时间的影响。要设置页限制,请对数据服务公开的每个实体集调用 SetEntitySetPageSize 方法。有关详细信息,请参阅How to: Enable Paging of Data Service Results (WCF Data Services)

在 WCF Data Services 中启用 $format 系统查询选项
WCF Data Services 同时支持 Atom XML 和 JSON,这是 OData 所要求的。WCF Data Services 接收请求时,它检查 Accept 请求标头以确定响应的格式。OData 还提供 $format 查询选项,无法设置请求标头的客户端可以使用该选项,如某些 JavaScript 客户端和浏览器。默认情况下,WCF Data Services 忽略此系统查询选项。有关详细信息,请参阅 WCF Data Services Protocol Implementation Details

在调用 OData 服务时,启用对 $format 查询选项的支持也会在客户端 JavaScript 网页代码中启用对“带填充的 JavaScript 对象符号” (JSONP) 的支持。您可以通过从 MSDN 代码库网站下载对 WCF Data Services 的 JSONP 和 URL 控制的格式支持示例项目并将它添加到您的数据服务项目,来将此功能添加到您的数据服务。

OData 客户端的指南

本节介绍对访问 OData 服务的客户端支持级别和访问 OData 服务的客户端的指南。

对访问 OData 服务的客户端支持
因为 OData 基于标准 Internet 协议,所以,可收发 HTTP 消息且可编写、分析 XML 或 JSON 的任何客户端都可以访问 OData 服务。为了减少访问 OData 服务所需的工作量,我们提供了各种用于使用 OData 服务的客户端库和客户端应用程序,其中包括:

有关 OData 客户端库的完整列表,请参阅 OData SDK。有关使用 OData 源的应用程序列表,请参阅 OData 网站上的使用者页

移动客户端注意事项
下面的注意事项适用于从移动设备应用程序访问 OData 源的情况:

  • 始终启用客户端分页,以便客户端可以控制获取服务发送的数据量。这通过在请求 URI 中使用 $skip$top 查询选项来实现。

  • 始终准备处理来自服务器的已分页响应。在 WCF Data Services 中,在查询 URI 中使用 $skiptoken 查询选项来请求下一页。有关详细信息,请参阅How to: Load Paged Results (WCF Data Services)

  • 如果您只需要源中项数的计数,请仅请求该计数值而非整个源。可以通过请求 $count 端点或在请求 URI 中包含 $inlinecount=allpages 来获取该计数。有关详细信息,请参阅How to: Determine the Number of Entities Returned by a Query (WCF Data Services)

  • 考虑使用 JSON 格式来替代 Atom XML 以减少占用网络带宽。

    note注意
    WCF Data Services 客户端(包括 OData client for Windows Phone)当前不支持 JSON 格式。

  • 考虑使用压缩来减少占用网络带宽。压缩需要数据服务和客户端设备进行额外处理。这种额外处理会对设备的电池寿命造成负面影响。

  • 考虑一些策略(如使用 $select 查询选项的客户端预测)来减少发送到客户端的数据量。有关详细信息,请参阅Query Projections (WCF Data Services)

  • 在客户端缓存引用数据或实施一些其他同步策略来减少从数据服务下载的重叠数据量。有关详细信息,请参阅Windows Azure 与移动客户端之间的数据同步

有关特定于 Windows Phone 平台的指南,请参阅将 Windows Phone 与 Windows Azure 配合使用


生成日期:

2013-05-16
本文是否对您有所帮助?
(1500 个剩余字符)

社区附加资源

添加
Microsoft 正在进行一项网上调查,以了解您对 MSDN 网站的意见。 如果您选择参加,我们将会在您离开 MSDN 网站时向您显示该网上调查。

是否要参加?
© 2013 Microsoft. 版权所有。
facebook page visit twitter rss feed newsletter