努力将 JSON 字符串转换为对象

Struggling to convert JSON string into an object

我正在努力解决如何将以下报价 JSON 数据转换为 C# 对象:

{"MyFeed":
{"@Provider":"SomeProvider","MMM":
    {"@name":"3M Corp","low":"194.80","high":"136.78","change":"2.80","pctchange":"0.22","ask":"135.15","bid_time":"20161104131845","bid":"134.80"}
}}

我创建了一个 C# class 像这样:

public class Quote
{
   public string Provider { get; set; }
   public Data Info { get; set; }
}

public class Data
{
  public string name { get; set; }
  public decimal low { get; set; }
  public decimal high { get; set; }
  public decimal change { get; set; }
  public decimal pctchange { get; set; }
  public decimal ask { get; set; }
  public DateTime bid_time { get; set; }
  public decimal bid { get; set; }
}

然后,在代码中,我使用 HttpWebRequest 获取数据,它运行得很好。但是反序列化 JSON 数据的步骤不起作用。它不会抛出错误,它只是没有数据。该代码是:

    var request = HttpWebRequest.Create(new Uri("<request URL here>")) as HttpWebRequest;
    request.Method = "POST";
    var response = request.GetResponse();
    using (Stream stream = response.GetResponseStream())
    {
        using (var reader = new StreamReader(stream))
        {
            Quote quote = JsonConvert.DeserializeObject<Quote>(reader.ReadToEnd());
            lblPrice.Text = string.Format("{0:c}", quote.Data.ask);
        }
    }

我单步执行了代码,所以我知道 Web 请求正在运行并返回 JSON 字符串。我只是不知道如何构造 C# class 来接受反序列化数据。帮助将不胜感激!

您应该像这样定义属性。

[JsonProperty(PropertyName = "@Provider")]
public string Provider { get; set; }

[JsonProperty(PropertyName = "@name")]
public string name { get; set; }

您还有许多其他问题,例如您的字段在 json 中不是十进制,错误的 class 结构。您的 class 应该是这样的:

    public class MyFeed
    {
        [JsonProperty(PropertyName = "@Provider")]
        public string Provider { get; set; }

        public MMM MMM { get; set; }
    }

    public class RootJsonObject
    {
        public MyFeed MyFeed { get; set; }
    }

    public class MMM
    {
        [JsonProperty(PropertyName = "@name")]
        public string name { get; set; }
        public string provider { get; set; }
        public string low { get; set; }
        public string high { get; set; }
        public string change { get; set; }
        public string pctchange { get; set; }
        public string ask { get; set; }
        public string bid_time { get; set; }
        public string bid { get; set; }
    }

您如何进行转换:

RootJsonObject quote = JsonConvert.DeserializeObject<RootJsonObject>(json);

你试过用这个吗json2csharp

您的报价 class 应该是可序列化的。使用 DataMembers 向其添加 Serializable 属性或向其添加 DataContract 属性。

  • 使用JsonProperty指定序列化字符串中的名称。
  • 当您传入一个包含您感兴趣的对象的对象时,您需要将整个 Quote 类型包装在不同的类型中。
  • 您需要指定 DateTime 类型的序列化方式。

这是一个完整且有效的解决方案,适用于您的 json。

class JsonTester
{
    public void Test()
    {
        const string json = "{\"MyFeed\":{\"@Provider\":\"SomeProvider\",\"MMM\":{\"@name\":\"3M Corp\",\"low\":\"194.80\",\"high\":\"136.78\",\"change\":\"2.80\",\"pctchange\":\"0.22\",\"ask\":\"135.15\",\"bid_time\":\"20161104131845\",\"bid\":\"134.80\"}}}";
        var settings = new JsonSerializerSettings()
        {
            DateFormatString = "yyyyMMddHHmmss"
        };
        var quoteWrapper = JsonConvert.DeserializeObject<MyFeed>(json, settings);
        var quote = quoteWrapper.Quote;
    }
}

public class MyFeed
{
    [JsonProperty("MyFeed")]
    public Quote Quote { get; set; }
}

public class Quote
{
    [JsonProperty("@Provider")]
    public string Provider { get; set; }
    [JsonProperty(PropertyName = "MMM")]
    public Data Info { get; set; }
}

public class Data
{
    [JsonProperty("@name")]
    public string name { get; set; }
    public decimal low { get; set; }
    public decimal high { get; set; }
    public decimal change { get; set; }
    public decimal pctchange { get; set; }
    public decimal ask { get; set; }
    public DateTime bid_time { get; set; }
    public decimal bid { get; set; }
}