JSON.net 反序列化对象嵌套数据

Posted

技术标签:

【中文标题】JSON.net 反序列化对象嵌套数据【英文标题】:JSON.net deserialize object nested data 【发布时间】:2018-10-03 03:49:19 【问题描述】:

我正在使用 SwiftType Elastic Search + C# 并遇到反序列化响应的问题,因为 SwiftType 将所有字段作为具有 raw 属性 (https://swiftype.com/documentation/app-search/api/search) 的对象返回,例如:


  "meta": 
    "warnings": [],
    "page": 
      "current": 1,
      "total_pages": 1,
      "total_results": 2,
      "size": 10
    ,
    "request_id": "6887a53f701a59574a0f3a7012e01aa8"
  ,
  "results": [
    
      "phone": 
        "raw": 3148304280.0
      ,
      "accounts_balance_ach": 
        "raw": 27068128.71
      ,
      "accounts_balance_pending": 
        "raw": "46809195.64"
      ,
      "email": 
        "raw": "Brisa34@hotmail.com"
      ,
      "accounts_count": 
        "raw": 6.0
      ,
      "id": 
        "raw": "c98808a2-d7d6-4444-834d-2fe4f6858f6b"
      ,
      "display_name": 
        "raw": "The Johnstons"
      ,
      "type": 
        "raw": "Couple"
      ,
      "advisor_email": 
        "raw": "Cornelius_Schiller14@hotmail.com"
      ,
      "created_at": 
        "raw": "2018-10-02T10:42:07+00:00"
      ,
      "source": 
        "raw": "event"
      ,
      "accounts_balance": 
        "raw": 43629003.47
      ,
      "accounts_donations": 
        "raw": 38012278.75
      ,
      "advisor_name": 
        "raw": "Cloyd Jakubowski"
      ,
      "_meta": 
        "score": 0.42934617
      
    ,
    
      "phone": 
        "raw": 2272918612.0
      ,
      "accounts_balance_ach": 
        "raw": 35721452.35
      ,
      "accounts_balance_pending": 
        "raw": "35117465.2"
      ,
      "email": 
        "raw": "Ruby87@yahoo.com"
      ,
      "accounts_count": 
        "raw": 1.0
      ,
      "id": 
        "raw": "687af11f-0f73-4112-879c-1108303cb07a"
      ,
      "display_name": 
        "raw": "Kennith Johnston"
      ,
      "type": 
        "raw": "Individual"
      ,
      "advisor_email": 
        "raw": "Evangeline_Wisoky92@hotmail.com"
      ,
      "created_at": 
        "raw": "2018-10-02T16:16:02+00:00"
      ,
      "source": 
        "raw": "website"
      ,
      "accounts_balance": 
        "raw": 23063874.19
      ,
      "accounts_donations": 
        "raw": 33025175.79
      ,
      "advisor_name": 
        "raw": "Ernie Mertz"
      ,
      "_meta": 
        "score": 0.39096162
      
    
  ]

我需要将每个键映射到它的值,例如 results[0].email = "Brisa34@hotmail.com";

我看到了promising option with custom converters,但我想确保在我采用详细方法之前没有更动态的方法来执行此操作。

【问题讨论】:

你想要这个 => results[0].email = "Brisa34@hotmail.com" 不是这个 => [results][0][email][raw] = "Brisa34@hotmail.com" 对吗? 另外,你可以在这里查看答案:***.com/questions/43399475/… 【参考方案1】:

我建议使用Can I specify a path in an attribute to map a property in my class to a child property in my JSON? 中的JsonPathConverter 类。这将允许您声明一个强类型的 Result 类,然后轻松地将每个属性映射到 JSON 中相应 raw 子值的值,而无需声明大量笨拙的单属性类。

如下所示声明您的模型。请注意,Result 类需要一个 [JsonConverter] 属性以将其绑定到 JsonPathConverter(否则属性路径将不起作用,您将在属性中获得默认值)。

public class RootObject

    public List<Result> results  get; set; 


[JsonConverter(typeof(JsonPathConverter))]
public class Result

    [JsonProperty("phone.raw")]
    public string Phone  get; set; 

    [JsonProperty("accounts_balance_ach.raw")]
    public decimal AccountsBalanceAch  get; set; 

    [JsonProperty("accounts_balance_pending.raw")]
    public decimal AccountsBalancePending  get; set; 

    [JsonProperty("email.raw")]
    public string Email  get; set; 

    [JsonProperty("accounts_count.raw")]
    public decimal AccountsCount  get; set; 

    [JsonProperty("id.raw")]
    public string Id  get; set; 

    [JsonProperty("display_name.raw")]
    public string DisplayName  get; set; 

    [JsonProperty("type.raw")]
    public string Type  get; set; 

    [JsonProperty("advisor_email.raw")]
    public string AdvisorEmail  get; set; 

    [JsonProperty("created_at.raw")]
    public string CreatedAt  get; set; 

    [JsonProperty("source.raw")]
    public string Source  get; set; 

    [JsonProperty("accounts_balance.raw")]
    public decimal AccountsBalance  get; set; 

    [JsonProperty("accounts_donations.raw")]
    public decimal AccountsDonations  get; set; 

    [JsonProperty("advisor_name.raw")]
    public string AdvisorName  get; set; 

    [JsonProperty("_meta.score")]
    public decimal MetaScore  get; set; 

然后你可以像往常一样反序列化:

var root = JsonConvert.DeserializeObject<RootObject>(json);

这是一个工作演示:https://dotnetfiddle.net/wYxwIF

【讨论】:

最具表现力和实用性的 +1 这正是我想要的! +1【参考方案2】:

对您来说最有活力的方式是使用The Newtonsoft JObejct class。

它会将你的 JSON 字符串解析成一个 JSON 对象供你使用,如果你没有相应的模型,你需要创建一个动态 JSON 对象。

例如

string json = "
  "meta": 
    "warnings": [],
    "page": 
      "current": 1,
      "total_pages": 1,
      "total_results": 2,
      "size": 10
    ,
    "request_id": "6887a53f701a59574a0f3a7012e01aa8"
  ,
  "results": [
    
      "phone": 
        "raw": 3148304280.0
      ,
      "accounts_balance_ach": 
        "raw": 27068128.71
      ,
      "accounts_balance_pending": 
        "raw": "46809195.64"
      ,
      "email": 
        "raw": "Brisa34@hotmail.com"
      ,
      "accounts_count": 
        "raw": 6.0
      ,
      "id": 
        "raw": "c98808a2-d7d6-4444-834d-2fe4f6858f6b"
      ,
      "display_name": 
        "raw": "The Johnstons"
      ,
      "type": 
        "raw": "Couple"
      ,
      "advisor_email": 
        "raw": "Cornelius_Schiller14@hotmail.com"
      ,
      "created_at": 
        "raw": "2018-10-02T10:42:07+00:00"
      ,
      "source": 
        "raw": "event"
      ,
      "accounts_balance": 
        "raw": 43629003.47
      ,
      "accounts_donations": 
        "raw": 38012278.75
      ,
      "advisor_name": 
        "raw": "Cloyd Jakubowski"
      ,
      "_meta": 
        "score": 0.42934617
      
    ,
    
      "phone": 
        "raw": 2272918612.0
      ,
      "accounts_balance_ach": 
        "raw": 35721452.35
      ,
      "accounts_balance_pending": 
        "raw": "35117465.2"
      ,
      "email": 
        "raw": "Ruby87@yahoo.com"
      ,
      "accounts_count": 
        "raw": 1.0
      ,
      "id": 
        "raw": "687af11f-0f73-4112-879c-1108303cb07a"
      ,
      "display_name": 
        "raw": "Kennith Johnston"
      ,
      "type": 
        "raw": "Individual"
      ,
      "advisor_email": 
        "raw": "Evangeline_Wisoky92@hotmail.com"
      ,
      "created_at": 
        "raw": "2018-10-02T16:16:02+00:00"
      ,
      "source": 
        "raw": "website"
      ,
      "accounts_balance": 
        "raw": 23063874.19
      ,
      "accounts_donations": 
        "raw": 33025175.79
      ,
      "advisor_name": 
        "raw": "Ernie Mertz"
      ,
      "_meta": 
        "score": 0.39096162
      
    
  ]
"

JObject result = JObject.Parse(json);

result 现在是一个 JSON 对象,您可以访问它的属性。

【讨论】:

【参考方案3】:

您可以使用以下link 将json 转换为C# 类。然后可以使用Newtonsoft Json来解析:

var jsonMessage = " \"meta\":   \"warnings\": [],  \"page\":    \"current\": 1,   \"total_pages\": 1,   \"total_results\": 2,   \"size\": 10  ,  \"request_id\": \"6887a53f701a59574a0f3a7012e01aa8\" , \"results\": [   \"phone\":     \"raw\": 3148304280.0   ,   \"accounts_balance_ach\":     \"raw\": 27068128.71   ,   \"accounts_balance_pending\":     \"raw\": \"46809195.64\"   ,   \"email\":     \"raw\": \"Brisa34@hotmail.com\"   ,   \"accounts_count\":     \"raw\": 6.0   ,   \"id\":     \"raw\": \"c98808a2-d7d6-4444-834d-2fe4f6858f6b\"   ,   \"display_name\":     \"raw\": \"The Johnstons\"   ,   \"type\":     \"raw\": \"Couple\"   ,   \"advisor_email\":     \"raw\": \"Cornelius_Schiller14@hotmail.com\"   ,   \"created_at\":     \"raw\": \"2018-10-02T10:42:07+00:00\"   ,   \"source\":     \"raw\": \"event\"   ,   \"accounts_balance\":     \"raw\": 43629003.47   ,   \"accounts_donations\":     \"raw\": 38012278.75   ,   \"advisor_name\":     \"raw\": \"Cloyd Jakubowski\"   ,   \"_meta\":     \"score\": 0.42934617     ,     \"phone\":     \"raw\": 2272918612.0   ,   \"accounts_balance_ach\":     \"raw\": 35721452.35   ,   \"accounts_balance_pending\":     \"raw\": \"35117465.2\"   ,   \"email\":     \"raw\": \"Ruby87@yahoo.com\"   ,   \"accounts_count\":     \"raw\": 1.0   ,   \"id\":     \"raw\": \"687af11f-0f73-4112-879c-1108303cb07a\"   ,   \"display_name\":     \"raw\": \"Kennith Johnston\"   ,   \"type\":     \"raw\": \"Individual\"   ,   \"advisor_email\":     \"raw\": \"Evangeline_Wisoky92@hotmail.com\"   ,   \"created_at\":     \"raw\": \"2018-10-02T16:16:02+00:00\"   ,   \"source\":     \"raw\": \"website\"   ,   \"accounts_balance\":     \"raw\": 23063874.19   ,   \"accounts_donations\":     \"raw\": 33025175.79   ,   \"advisor_name\":     \"raw\": \"Ernie Mertz\"   ,   \"_meta\":     \"score\": 0.39096162      ]";

var message = JsonConvert.DeserializeObject<RootObject>(jsonMessage);
Console.WriteLine(message.meta.page.current); // prints 1

public class Page

    public int current  get; set; 
    public int total_pages  get; set; 
    public int total_results  get; set; 
    public int size  get; set; 


public class Meta

    public List<object> warnings  get; set; 
    public Page page  get; set; 
    public string request_id  get; set; 


public class Phone

    public double raw  get; set; 


public class AccountsBalanceAch

    public double raw  get; set; 


public class AccountsBalancePending

    public string raw  get; set; 


public class Email

    public string raw  get; set; 


public class AccountsCount

    public double raw  get; set; 


public class Id

    public string raw  get; set; 


public class DisplayName

    public string raw  get; set; 


public class Type

    public string raw  get; set; 


public class AdvisorEmail

    public string raw  get; set; 


public class CreatedAt

    public DateTime raw  get; set; 


public class Source

    public string raw  get; set; 


public class AccountsBalance

    public double raw  get; set; 


public class AccountsDonations

    public double raw  get; set; 


public class AdvisorName

    public string raw  get; set; 


public class Meta2

    public double score  get; set; 


public class Result

    public Phone phone  get; set; 
    public AccountsBalanceAch accounts_balance_ach  get; set; 
    public AccountsBalancePending accounts_balance_pending  get; set; 
    public Email email  get; set; 
    public AccountsCount accounts_count  get; set; 
    public Id id  get; set; 
    public DisplayName display_name  get; set; 
    public Type type  get; set; 
    public AdvisorEmail advisor_email  get; set; 
    public CreatedAt created_at  get; set; 
    public Source source  get; set; 
    public AccountsBalance accounts_balance  get; set; 
    public AccountsDonations accounts_donations  get; set; 
    public AdvisorName advisor_name  get; set; 
    public Meta2 _meta  get; set; 


public class RootObject

    public Meta meta  get; set; 
    public List<Result> results  get; set; 

【讨论】:

以上是关于JSON.net 反序列化对象嵌套数据的主要内容,如果未能解决你的问题,请参考以下文章

Json.NET:将嵌套数组反序列化为强类型对象

使用 JSON.NET 反序列化任何内容

从 JSON 反序列化重复字典

使用 DataContractSerializer 发送反序列化的 Json.net 对象时出错

Json.Net以索引为名称反序列化JSON对象[重复]

使用JSON.Net将字符串属性值反序列化为类实例