2012-01-25 4 views
3

со ссылкой на Parse JSON in C#Разбор JSON пар ключ значение в C#

Я пытаюсь разобрать в C# следующий JSON feed и у меня есть проблемы с доступом к данным «ставки». Я попытался десериализовать это в List> или Dictionary, а также другие типы, которые всегда получают 0 результатов. Единственный способ, которым мне удалось это сделать, - создать пользовательский тип и иметь все валюты, которые мне нужны в качестве свойств, - что довольно приятно.

Вот мои текущие DataContracts:

[DataContract] 
    public class OpenExchangeRatesResult 
    { 
     public OpenExchangeRatesResult() { } 

     [DataMember] 
     public string disclaimer { get; set; } 

     [DataMember] 
     public RatesObj rates { get; set; } 

    } 

    [DataContract] 
    public class RatesObj 
    { 
     public RatesObj() { } 
     [DataMember] 
     public decimal EUR { get; set; } 
     [DataMember] 
     public decimal USD { get; set; } 
     [DataMember] 
     public decimal GBP { get; set; } 
     [DataMember] 
     public decimal AUD { get; set; } 
     [DataMember] 
     public decimal CAD { get; set; } 
     [DataMember] 
     public decimal CHF { get; set; } 
     [DataMember] 
     public decimal DKK { get; set; } 
     [DataMember] 
     public decimal LYD { get; set; } 
     [DataMember] 
     public decimal NZD { get; set; } 
     [DataMember] 
     public decimal SEK { get; set; } 
     [DataMember] 
     public decimal JPY { get; set; } 
     [DataMember] 
     public decimal ZAR { get; set; } 
    } 

Я хотел бы быть в состоянии заменить RatesObj с коллекцией своего рода.

Любые идеи?

ответ

3

Я использую JSON.net (документация here), который, вероятно, похож на DataContractJsonSerializer, но я просто заменить ваши RatesObj с Dictionary<string,decimal>:

[DataContract] 
public class OpenExchangeRatesResult 
{ 
    public OpenExchangeRatesResult() { } 
    [DataMember] 
    public string disclaimer { get; set; } 
    [DataMember] 
    public Dictionary<string, decimal> rates { get; set; } 
} 

И мой тестовый код:

class Program 
{ 
    static void Main(string[] args) 
    { 
     HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(@"https://raw.github.com/currencybot/open-exchange-rates/master/latest.json"); 
     wr.Timeout = 30 * 1000; 
     HttpWebResponse response = (HttpWebResponse)wr.GetResponse(); 
     using (var s = new StreamReader(response.GetResponseStream())) 
     { 
      string json = s.ReadToEnd(); 

      var oerr = JsonConvert.DeserializeObject<OpenExchangeRatesResult>(json); 

      Console.WriteLine(json); 
     } 
    } 
} 

В итоге у меня есть тарифы собственности havi nh приблизительно 150 записей строк (название валюты) и десятичных знаков (ставки). Надеюсь, это то, что вы ищете.

Надеюсь, это поможет. Дайте мне знать, если у вас есть другие вопросы, и я уточню свой ответ.

Удачи вам!

0

Попробуйте JSon.Net, это отличная библиотека.

http://json.codeplex.com

+0

Я согласен с тем, что JSON.net является превосходным, но на самом деле это не отвечает на его вопрос. Он хочет избавиться от своего RateObj и использовать что-то более динамичное. –

0

(IMHO было бы здорово, если бы IExtensibleDataObject можно было использовать для такого рода вещей, но поскольку ExtensionDataObject полностью непрозрачен, он явно запрещен. Конечно, вы можете извлечь внутренний словарь с помощью Reflection, но нет никаких гарантий для поведения, если вы сделайте это)

Можно использовать: JsonReaderWriterFactory.CreateJsonReader для создания объекта XmlReader, который позволяет использовать более динамическую схему. Использование XmlReaders в большинстве случаев болезненно, поэтому я не могу утверждать, что этот код идеален, но, возможно, он может служить источником вдохновения.

using System; 
using System.Collections.Generic; 
using System.Dynamic; 
using System.Net; 
using System.Runtime.Serialization.Json; 
using System.Xml; 

namespace ConsoleApplication1 
{ 

    class Program 
    { 
     static dynamic RecursiveBuildUp (XmlReader reader) 
     { 
      object result = null; 
      while (reader.Read()) 
      { 
       switch (reader.NodeType) 
       { 
        case XmlNodeType.Element: 
         // TODO: It seems array elements are identified with the an "item" key 
         // This can create problems if the json object has a property name "item" 
         if (reader.LocalName == "item") 
         { 
          var list = result as List<object>; 
          if (list == null) 
          { 
           list = new List<object>(); 
           result = list; 
          } 
          list.Add (RecursiveBuildUp (reader)); 
         } 
         else 
         { 
          var dic = result as IDictionary<string, object>; 
          if (dic == null) 
          { 
           dic = new ExpandoObject(); 
           result = dic; 
          } 
          var localName = reader.LocalName; 
          dic[localName] = RecursiveBuildUp (reader); 
         } 
         break; 
        case XmlNodeType.Text: 
         result = reader.Value; 
         break; 
        case XmlNodeType.EndElement: 
         return result; 
        default: 
         throw new Exception ("Unhandled node type: " + reader.NodeType); 
       } 
      } 
      return result; 
     } 

     static void Main (string[] args) 
     { 
      var wc = new WebClient(); 
      var json = wc.DownloadData ("https://raw.github.com/currencybot/open-exchange-rates/master/latest.json"); 

      var quotas = new XmlDictionaryReaderQuotas(); 
      var reader = JsonReaderWriterFactory.CreateJsonReader (json, quotas); 

      var result = RecursiveBuildUp (reader); 
      Console.WriteLine (result.root.rates.AED); 
     } 
    } 
} 
Смежные вопросы