簡體   English   中英

如何在C#中將JSON反序列化為復雜對象

[英]How to deserialize JSON to complex object in C#

我正在嘗試將json結果反序列化為想要的對象。 我得到的結果是:

{
    "base": "EUR",
    "date": "2017-06-30",
    "rates": {
        "AUD": 1.4851,
        "BGN": 1.9558,
        "BRL": 3.76,
        "CAD": 1.4785
    }
}

我希望此結果反序列化到我的對象:

public class ExchangeRates
{
    public string Base { get; set; }

    public DateTime Date { get; set; }

    public IList<Rates> Rates { get; set; }
}

public class Rates
{
    public string Name { get; set; }

    public decimal Value { get; set; }
}

我的反序列化看起來像這樣:

 using (var httpClient = new HttpClient())
 {
     var response = httpClient.GetAsync("http://api.fixer.io/latest").Result;
     var result = response.Content.ReadAsStringAsync().Result;
     var values = JsonConvert.DeserializeObject<ExchangeRates>(result);
 }

當我運行程序時,出現以下異常:

Newtonsoft.Json.JsonSerializationException:'無法反序列化當前JSON對象(例如{“ name”:“ value”})為類型'System.Collections.Generic.List`1 [ConsoleApp4.Rates]',因為該類型需要JSON數組(例如[1,2,3])正確反序列化。 要解決此錯誤,可以將JSON更改為JSON數組(例如[1,2,3]),也可以更改反序列化類型,使其成為普通的.NET類型(例如,不像整數這樣的原始類型,也不像這樣的集合類型)數組或列表),可以從JSON對象反序列化。 還可以將JsonObjectAttribute添加到類型中,以強制其從JSON對象反序列化。 路徑“ rates.AUD”,第1行,位置49。”

如何將JSON反序列化為想要的對象?

更新1

還是我可以反序列化“費率”列表?

看一下您的JSON,特別是rates

"rates": {
    "AUD": 1.4851,
    "BGN": 1.9558,
    "BRL": 3.76,
    "CAD": 1.4785
}

很明顯,這是一個JSON對象,因為它具有鍵值對。 但是,查看您的代碼,您已將相應的屬性( Rates )定義為IList

public IList<Rates> Rates { get; set; }

我們了解您定義Rates類背后的原因。 您認為通過定義該類,NewtonSoft將以您希望的方式反序列化rates 但是,這是不可能的,因為rates不是數組,因此將其反序列化為任何種類的IList是不可能的。

最簡單,最明確的解決方案是使用字典:

public Dictionary<string, decimal> Rates { get; set; }

但是,如果您不想使用字典,則需要像這樣修改JSON,您的解決方案將起作用:

"rates":[  
  {  
     "Name":"AUD",
     "Value":1.4851
  },
  {  
     "Name":"BGN",
     "Value":1.9558
  },
  {  
     "Name":"BRL",
     "Value":3.76
  },
  {  
     "Name":"CAD",
     "Value":1.4785
  }
]

通過將rates轉換為數組,並使其內容對象而不是鍵值對,NewtonSoft可以將rates反序列化為列表,並將其內容反序列化為Rates類的實例。

我同意其他人的意見:您應該使用字典。 為了實現到最終對象結構的轉換,您可以使用例如帶有顯式強制轉換運算符的中間類。

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

public class Program
{
    public void Main()
    {
        var result = @"{
        ""base"": ""EUR"",
        ""date"": ""2017-06-30"",
        ""rates"": {
            ""AUD"": 1.4851,
            ""BGN"": 1.9558,
            ""BRL"": 3.76,
            ""CAD"": 1.4785
        }}";

        var values = (ExchangeRates) JsonConvert.DeserializeObject<TempExchangeRates>(result);


        Console.WriteLine(values.Base);
        Console.WriteLine(values.Date);

        foreach(var rate in values.Rates)
            Console.WriteLine(rate.Name + ": " + rate.
    }
}

public class TempExchangeRates
{
    public string Base { get; set; }
    public DateTime Date { get; set; }
    public Dictionary<string,decimal> Rates { get; set; }
    public static explicit operator ExchangeRates(TempExchangeRates tmpRates)
    {
        var xRate = new ExchangeRates();

        xRate.Base = tmpRates.Base;
        xRate.Date = tmpRates.Date;
        xRate.Rates = new List<Rates>();

        foreach(var de in tmpRates.Rates)
            xRate.Rates.Add(new Rates{Name = de.Key, Value = de.Value});

        return xRate;
    }
}


public class ExchangeRates
{
    public string Base { get; set; }
    public DateTime Date { get; set; }
    public IList<Rates> Rates { get; set; }
}

public class Rates
{
    public string Name { get; set; }
    public decimal Value { get; set; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM