代码之家  ›  专栏  ›  技术社区  ›  iMajna

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

  •  0
  • iMajna  · 技术社区  · 7 年前

    我试图找出当每个列表元素都可以有不同的属性时如何反序列化对象。

    例如,假设我必须选择“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”可以为空或不应可见,但当类型==A时,town应可见。

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

    1 回复  |  直到 7 年前
        1
  •  0
  •   Connell.O'Donnell    7 年前

    你可以通过 NullValueHandling 标志到 JsonProperty 属性(如果您使用的是newtonsoft)。以下是他们文档中的一个示例:

    https://www.newtonsoft.com/json/help/html/JsonPropertyPropertyLevelSetting.htm

    编辑 尝试创建以下对象结构:

    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 });
        }
    }