如何将json反序列化为对象集合

时间:2017-05-17 21:01:34

标签: c# .net json serialization

我有以下JSON(我无法改变来自第三方系统的传入JSON):

{
  "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&#39; JsonConvert.DeserializeObject(json);时,User.Tags属性始终为空。这显然是因为没有&#34;标签&#34;根据&#34;标签&#34;属性。

然而,如果我按如下方式更改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对象   (例如{&#34; name&#34;:&#34; value&#34;})进入类型   &#39; System.Collections.Generic.List`1 [代码]&#39;因为类型需要    一个JSON数组(例如[1,2,3])以正确反序列化。

有关创建User类以使其正确反序列化的任何建议都将非常感激。

修改

所以这可能是也可能不是最佳答案,但它确实有效。进入的标签将是十几个不同的名称之一。所以我创建了一个Tags类,其中包含12个possibilites中的每一个的属性。由于不需要,所以出现的任何一个都会被填充。以下是我调整后的用户,标签(以前称为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不是数组或集合,而是具有名称/值配对的唯一属性名称列表。

3 个答案:

答案 0 :(得分:0)

不确定您的JSON是否正确,但为什么您的媒体资源名称Employee IDJob Family中有空格。修复Tags类中的那些,我们很高兴。

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

得到的

答案 1 :(得分:0)

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

如果tags中的键是动态/更改的,那么可以尝试

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

修改

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

答案 2 :(得分:0)

好好使用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);