3

参考Parse JSON in C#

我正在尝试在 C# 中解析以下JSON 提要,但在访问“rates”中的数据时遇到问题。我试图将其反序列化为 List> 或 Dictionary 以及其他各种类型,但我总是得到 0 个结果。我设法让它工作的唯一方法是创建一个自定义类型并将我需要的所有货币作为属性——这非常好。

这是我目前的数据合同:

    [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。

有任何想法吗?

4

3 回答 3

3

我正在使用JSON.net此处的文档),它可能类似于 DataContractJsonSerializer,但我只是将您的替换RatesObjDictionary<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);
        }
    }
}

我最终得到 rate 属性,其中包含大约 150 个字符串(货币名称)和小数(汇率)条目。希望这是您正在寻找的。

我希望这有帮助。如果您有其他问题,请告诉我,我会详细说明我的答案。

祝你好运!

于 2012-01-25T13:51:07.400 回答
0

试试 JSon.Net,它是一个很棒的库。

http://json.codeplex.com

于 2012-01-25T13:44:07.263 回答
0

(恕我直言,如果可以将 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);
        }
    }
}
于 2012-01-25T19:23:16.057 回答