資料點

創建和使用 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