【问题标题】:How to deserialize json into collection of Objects如何将json反序列化为对象集合
【发布时间】:2017-05-17 21:01:34
【问题描述】:

我有以下 JSON(我无法更改传入的 JSON,因为它来自第 3 方系统):

{
  "id": 23,
  "userName":"test@test.com",
  "tags":
  {
     "Employee ID":
     {
        "name":"Employee ID",
        "value":"123456789"
     },
     "Job Family":
     {
       "name": "Job Family",
       "value": "Accounting and Finance"
     }
  }
}

首先,我尝试使用这个类结构进行反序列化:

public class User
{

    [JsonProperty("id")]
    public int ID { get; set; }
    [JsonProperty("username")]
    public string Email { get; set; }
    [JsonProperty("tags")]
    public TagsJson Tags { get; set; }
}

public class TagsJson
{
    [JsonProperty("tags")]
    public List<Tag> Tags { get; set; }
}

public class Tag
{
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("value")]
    public string Value { get; set; }
}

在使用 Newtonsoft 的 JsonConvert.DeserializeObject(json); 时,User.Tags 属性始终为空。这显然是因为“Tags”属性下没有“Tags”。

但是,如果我按如下方式更改 User 类...

public class User
{

    [JsonProperty("id")]
    public int ID { get; set; }
    [JsonProperty("email")]
    public string Email { get; set; }
    [JsonProperty("tags")]
    public List<Tag> Tags { get; set; }
    // I even tried Tag[] instead of List<Tag> here
}

...我收到以下错误:

附加信息:无法反序列化当前 JSON 对象 (例如 {"name":"value"}) 转换为类型 'System.Collections.Generic.List`1[Tag]' 因为类型需要 正确反序列化的 JSON 数组(例如 [1,2,3])。

任何关于创建 User 类以使其正确反序列化的建议将不胜感激。


编辑

所以这可能是也可能不是最好的答案,但它确实有效。进来的标签将是十几个不同名称中的一个。因此,我为 12 种可能性中的每一种创建了一个带有属性的标签类。由于没有一个是必需的,因此出现的任何一个都会被填充。下面是我调整后的 User、Tags(以前的 TagsJson)和 Tag 类 - 但我肯定对更好的解决方案感兴趣。

public class User
{

    [JsonProperty("id")]
    public int ID { get; set; }
    [JsonProperty("username")]
    public string Email { get; set; }
    [JsonProperty("tags")]
    public Tags AllTags { get; set; }
}

public class Tags
{
    [JsonProperty("Employee ID")]
    public Tag EmployeeID { get; set; }
    [JsonProperty("Job Family")]
    public Tag JobFamily { get; set; }        
    // ... and 10 more properties for additional tags that may appear but are not required
}

public class Tag 
{
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("value")]
    public string Value { get; set; }
}

this question 的建议答案在我的情况下不起作用,因为 JSON 不是数组或集合,而是具有名称/值对的唯一属性名称列表。

【问题讨论】:

  • 示例中的标签是单个对象。如果它是一个数组,它会被包裹在[]
  • @Zinov 这两个问题都是关于 json 反序列化的,这个问题的答案非常简单,并且在 stackoverflow 上已经有足够的信息来解决它。但是,此问题专门针对反序列化特定架构,该架构与您链接的问题中的数据架构不同。

标签: c# .net json serialization


【解决方案1】:

使用Visual Studio paste Json as classes 产生...

public class Rootobject
{
    public int id { get; set; }
    public string userName { get; set; }
    public Tags tags { get; set; }
}

public class Tags
{
    [JsonProperty(PropertyName = "Employee ID")]
    public EmployeeID EmployeeID { get; set; }

    [JsonProperty(PropertyName = "Job Family")]
    public JobFamily JobFamily { get; set; }
}

public class EmployeeID
{
    public string name { get; set; }
    public string value { get; set; }
}

public class JobFamily
{
    public string name { get; set; }
    public string value { get; set; }
}

我必须自己添加 JsonProperty 属性。但是我认为更好的解决方案是......

public class Rootobject2
{
    public int id { get; set; }
    public string userName { get; set; }
    public IDictionary<string, NameValuePair> tags { get; set; }
}
public class NameValuePair
{
    public string name { get; set; }
    public string value { get; set; }
}

虽然将 Json 粘贴为类是一个很好的起点,可以轻松地将代码复制并粘贴到首选解决方案中。

一些测试代码...

string json = Resource1.String1;

Rootobject test = JsonConvert.DeserializeObject<Rootobject>(json);

Rootobject2 test2 = JsonConvert.DeserializeObject<Rootobject2>(json);

【讨论】:

  • 这个答案效果很好 - 显示如何将 JSON 粘贴到类中的链接非常有用。我把它放到我的代码中,一切正常。我将此标记为解决方案并给了它+1(它没有出现,因为我在这个网站上仍然太新)。感谢您的帮助!
【解决方案2】:

不确定您的 JSON 是否正确,但为什么您的属性名称 Employee IDJob Family 中有空格。修复标签类中的那些,我们很高兴。

public class EmployeeID
{
    public string name { get; set; }
    public string value { get; set; }
}

public class JobFamily
{
    public string name { get; set; }
    public string value { get; set; }
}

public class Tags
{
    public EmployeeID __invalid_name__Employee ID { get; set; }
    public JobFamily __invalid_name__Job Family { get; set; }
}

public class User
{
    public int id { get; set; }
    public string userName { get; set; }
    public Tags tags { get; set; }
}

这是我从json2csharp.com得到的

【讨论】:

  • 我做了同样的事情 - 得到了相同的结果 - “无效名称”部分似乎暗示 JSON 无效?
  • @motor75:您需要从其来源确认此 JSON。
  • 不需要更改属性名称。 “无效名称”是因为您不能在 C# 中使用带有空格的属性名称,但您可以在 Javascript 中使用。该名称并非无效 - 只是 C# 没有那么富有表现力。尝试使用[JsonProperty("Employee ID")] public string EmployeeId { get; set; } 或类似的
【解决方案3】:

您的 JSON 显示您的 tags 对象是 Object - 而不是 Array。您不能将 Object 反序列化为 C# List,因为它们是不同的结构。

如果tags 中的键是动态/变化的,那么不妨试试

[JsonProperty("tags")]
Dictionary<string, string> Tags { get; set; }

编辑

看来您的 JSON 格式不正确;如果您无法修改它,您可能必须使用自定义 JsonConverter

【讨论】:

  • 我认为这是解决方案 - 除了我收到此错误:附加信息:解析值时遇到意外字符:{。 Path 'tags['Employee ID']', line 1, position 835 看来“Employee ID”需要去掉空格?
  • 好吧,我删除了空格(添加了一个下划线),但没有修复它:解析值时遇到意外字符:{。路径“tags.Employee_ID”,第 1 行,位置 835。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多