将json反序列化为对象:包装器类的解决方案

本文关键字:解决方案 包装 json 反序列化 对象 | 更新日期: 2023-09-27 18:09:27

这是我的json

{
    "accessType":"Grant",
    "spaces":[{"spaceId":"5c209ba0-e24d-450d-8f23-44a99e6ae415"}],
    "privilegeId":"db7cd037-6503-4dbf-8566-2cca4787119d",
    "privilegeName":"PERM_RVMC_DEV",
    "privilegeDescription":"RVMC Dev",
    "privilegeType":"Permission"
}

这是我的类:

public class ProfilePrivilege
{
    public AccessType AccessType { get; set; }
    public Guid PrivilegeId { get; set; }
    public string PrivilegeName { get; set; }
    public string PrivilegeDescription { get; set; }
    public PrivilegeType PrivilegeType { get; set; }
    public List<Guid> spaces;
}

当空格数组不为空时,我得到反序列化错误。我可以通过简单地为Guid

创建一个包装器类来解决这个问题
public class Space
{
    public Guid spaceId;   
}
而不是List<Guid>,我可以有一个List<Space>在我的特权类,这一切都很好。但我想知道是否有更好的方法来做到这一点,因为我不想有一个冗余的包装器类。那么,在不为我的特权类型对象编写自定义反序列化器的情况下,有什么简单的方法可以解决这个问题吗?

我用JSON反序列化。顺便说一句。

将json反序列化为对象:包装器类的解决方案

您可以使用一个简单的JsonConverter类将spaces对象数组扁平化为guid列表,从而消除了对包装器类的需求。

下面是你需要的转换器代码:

class SpaceListConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(List<Guid>));
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return JArray.Load(reader)
                     .Children<JObject>()
                     .Select(jo => Guid.Parse((string)jo["spaceId"]))
                     .ToList();
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

要使用它,在ProfilePrivilege类中用[JsonConverter]属性注释Spaces属性,如下所示:

public class ProfilePrivilege
{
    ...
    [JsonConverter(typeof(SpaceListConverter))]
    public List<Guid> Spaces;
    ...
}

然后,当你反序列化时,一切都应该"正常工作"。

完整的演示在这里:https://dotnetfiddle.net/EaYgbe

您不一定需要创建poco。另一种选择是使用dynamics:

dynamic d = JObject.Parse(jsonString);
Console.WriteLine(d.accessType);
Console.WriteLine(d.spaces.Count);
Console.WriteLine(d.spaces[0].spaceId);