使用条件json.net反序列化对象

时间:2018-11-27 19:17:05

标签: c# serialization json.net deserialization

我试图弄清楚当每个列表元素可以具有不同的属性时如何反序列化对象。

例如,假设我必须选择选项“ a”和“ b”:

{
  "Email": "james@example.com",
  "CreatedDate": "2013-01-20T00:00:00Z",
  "Roles": [{
    "name": "test",
    "type": "a",
    "town": "xyz"
  },
  {
    "name": "test1",
    "type": "b" 
  }]
}

当类型== b时,“ town”可以为null或不可见,但是当类型== a时,town应该可见。

我厌倦了通过序列化删除可为空的字段,但是当我尝试反序列化我的类结构时,只需将“ town”添加到具有空值的每个元素中,这是期望的,因为类结构看起来像那样。类结构应该如何?

1 个答案:

答案 0 :(得分:0)

如果您使用的是Newtonsoft,则可以将NullValueHandling标志传递给JsonProperty属性。这是他们的文档中的一个示例:

Object.values()

修改 尝试创建以下对象结构:

public class Person
{
    public string Email { get; set; }
    public DateTime CreatedDate { get; set; }
    public List<Role> Roles { get; set; }
}

public class Role
{
    public string name { get; set; }
    public string type { get; set; }

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string town { get; set; }
}

然后将json复制到文件中,然后反序列化

string json = File.ReadAllText("a.json");
Person person = JsonConvert.DeserializeObject<Person>(json);

修改

好吧,如果您真的根本不想看到该属性,那么您将得到一些丑陋的代码。这是一个快速有效的示例。

public class PersonA
{
    public string Email { get; set; }
    public DateTime CreatedDate { get; set; }
    public List<RoleB> Roles { get; set; }       
}

public class RoleB : RoleA
{
    public string town { get; set; }
}

public class PersonB
{
    public string Email { get; set; }
    public DateTime CreatedDate { get; set; }
    public List<RoleA> RolesA { get; set; } = new List<RoleA>();
    public List<RoleB> RolesB { get; set; } = new List<RoleB>();
}

public class RoleA
{
    public string name { get; set; }
    public string type { get; set; }
}

然后做这样的事情:

string json = File.ReadAllText("a.json");
PersonA personA = JsonConvert.DeserializeObject<PersonA>(json);
PersonB personB = new PersonB() { Email = personA.Email, CreatedDate = personA.CreatedDate };

foreach(var role in personA.Roles)
{
    var roleB = role as RoleB;
    if (roleB.town != null)
    {
        personB.RolesB.Add(roleB);
    }
    else
    {
        personB.RolesA.Add(new RoleA() { name = roleB.name, type = roleB.type });
    }
}