2013-01-04 88 views
18

我使用JSON.NET從openexhangerates.org服務器端使用.NET解析JSON響應。該響應包含嵌套的對象(「速率」),其具有數值屬性一長串:將JSON.NET JObject的屬性/標記轉換爲字典鍵

{ 
    "disclaimer": "Exchange rates provided for informational purposes only, with no guarantee whatsoever of accuracy, validity, availability, or fitness for any purpose; use at your own risk. Other than that, have fun! Usage subject to acceptance of terms: http://openexchangerates.org/terms/", 
    "license": "Data sourced from various providers with public-facing APIs; copyright may apply; not for resale; no warranties given. Usage subject to acceptance of license agreement: http://openexchangerates.org/license/", 
     "timestamp": 1357268408, 
     "base": "USD", 
     "rates": { 
      "AED": 3.673033, 
      "AFN": 51.5663, 
      "ALL": 106.813749, 
      "AMD": 403.579996, 
      etc... 
     } 
    } 

的屬性名稱對應於貨幣類型(例如,「USD」)。我需要假設屬性列表可以隨時間變化,所以我想將對象轉換爲Dictionary而不是相應的C#對象。的

因此,而不是反序列化JSON對象弄成這個樣子:

class Rates 
{ 
public decimal AED; // United Arab Emirates Dirham 
public decimal AFN; // Afghan Afghani 
public decimal ALL; // Albanian Lek 
public decimal AMD; // Armenian Dram 
// etc... 
} 

我想這結束了:

Dictionary<string,decimal>() {{"AED",0.2828},{"AFN",0.3373},{"ALL",2.2823},{"AMD",33.378} // etc...}; 

我如何做到這一點無論從響應字符串開始或從JObject調用JObject.Parse(responseString)生成?

+1

你看過谷歌搜索結果如何反序列化使用C#的JSON有很多互聯網上的例子.. http://stackoverflow.com/questions/6375122/how-to-parse-json-response-進入詞典 – MethodMan

回答

25

JObject已經實現了IDictionary<string, JToken>,所以我懷疑,當您瀏覽到的rates會員,你應該能夠使用:

var result = rates.ToDictionary(pair => pair.Key, pair => (decimal) pair.Value); 

不幸的是,它使用顯式接口實現,這使它成爲一個位的痛苦 - 但如果你通過IDictionary<string, JToken>界面,它沒問題。

這裏的出現與您所提供的JSON(保存到一個文件test.json)工作的一個簡短但完整的例子:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using Newtonsoft.Json.Linq; 

class Test 
{ 
    static void Main() 
    { 
     JObject parsed = JObject.Parse(File.ReadAllText("test.json")); 
     IDictionary<string, JToken> rates = (JObject) parsed["rates"]; 
     // Explicit typing just for "proof" here 
     Dictionary<string, decimal> dictionary = 
      rates.ToDictionary(pair => pair.Key, 
           pair => (decimal) pair.Value); 
     Console.WriteLine(dictionary["ALL"]); 
    } 
} 
+0

我如何「導航」到「費率」?當我嘗試使用jo [「rates」]時,得到一個JToken - 不是JObject。 – Emmanuel

+1

@Canoehead:你需要投射到'JObject'。查看我的編輯完整示例。 –

+0

你永遠不會驚訝於你的知識和樂於助人! – Emmanuel

6

這是否對你的工作?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Newtonsoft.Json.Linq; 

namespace JsonNetTest 
{ 



    class Program 
    { 
     static void Main(string[] args) 
     { 

      string jsonString = @"{ 
       'disclaimer': 'Exchange rates provided for informational purposes only, with no guarantee whatsoever of accuracy, validity, availability, or fitness for any purpose; use at your own risk. Other than that, have fun! Usage subject to acceptance of terms: http://openexchangerates.org/terms/', 
       'license': 'Data sourced from various providers with public-facing APIs; copyright may apply; not for resale; no warranties given. Usage subject to acceptance of license agreement: http://openexchangerates.org/license/', 
       'timestamp': 1357268408, 
       'base': 'USD', 
       'rates': { 
        'AED': 3.673033, 
        'AFN': 51.5663, 
        'ALL': 106.813749, 
        'AMD': 403.579996 
       } 
      }"; 

      JObject parsed = JObject.Parse(jsonString); 

      Dictionary<string, decimal> rates = parsed["rates"].ToObject<Dictionary<string, decimal>>(); 

      Console.WriteLine(rates["ALL"]); 

      Console.ReadKey(); 

     } 
    } 
} 
1

如果你希望子對象有一個對象屬性(或領域),最好使用:

Dictionary<string, object> rates = parsed["rates"].ToObject<Dictionary<string, object>>(); 

否則,它會拋出一個錯誤。

+0

我發現這是訪問密鑰最簡單的方法。我用你的答案來回答http://stackoverflow.com/questions/6522358/how-can-i-get-a-list-of-keys-from-json-net/ – Blairg23