首页 > 解决方案 > 反序列化具有不同表示的对象

问题描述

我想反序列化一个 JSON 文档,该文档包含以两种不同方式表示的相同类型 User 的对象,作为完整对象表示或按名称对现有用户对象的引用:

[
    {
        "User": "SomeUser"
    },
    {
        "User": {
            "Login": "SomeOtherUser",
            "Active": true
        }
    }
]

编写一个处理按名称引用的用户对象的转换器很容易:

class User
{
    public string Id;
    public string Login;
    public bool Active;
}
    
class Document
{
    public User User;
}

class UserConverter : JsonConverter
{
    public UserConverter(Dictionary<string, User> users)
    {
        _users = users;
    }

    public override bool CanConvert(Type objectType)
    {
        var res = typeof(User).IsAssignableFrom(objectType);
        return res;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var name = ((User)value)?.Login;
        writer.WriteValue(name);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var name = reader.Value?.ToString();
        if (string.IsNullOrEmpty(name))
            return null;
        _users.TryGetValue(name, out var res);
        return res;
    }

    readonly Dictionary<string, User> _users;
}
// ....
    static void Test2()
    {
        var settings = new JsonSerializerSettings
        {
            MissingMemberHandling = MissingMemberHandling.Error,
            Converters =
            {
                new UserConverter(new Dictionary<string, User> { { "SomeUser", new User() }})
            }
        };
        var data = JsonConvert.DeserializeObject<List<Document>>("[{\"User\": \"SomeUser\"}, {\"User\": {\"Login\": \"SomeUser\",\"Active\": true}}]", settings);
    }

但是,当遇到完整的用户对象时,这会导致反序列化错误:“Newtonsoft.Json.JsonSerializationException:'在'文档'类型的对象上找不到成员'登录'。路径'[1] .User.Login'”
任何想法如何让它支持两者?

标签: c#.netjson.net

解决方案


推荐阅读