在JsonContract中使用默认对象构造

时间:2019-03-20 08:13:14

标签: c# json.net

使用构造函数参数反序列化对象时,默认的序列化程序可以对其中一些对象使用null。但是,如果要通过JsonContract创建对象并调用DefaultCreator,则会得到一个NullReferenceException

有没有一种方法可以对我用ResolveContract(..)解析的类型使用相同的实例化逻辑?我想避免将无参数构造函数添加到我正在使用的所有受影响的类型中。

这意味着,我希望我的自定义转换器能够通过为未指定的构造函数参数注入null来初始化对象,就像第一次调用DeserializeObject那样,它不使用自定义转换器。


我已经创建了这个小的概念验证演示,以向您展示我的意思:

void Main()
{
    var json = @"
    {
        'User': {
            'Age': 80
        }

    }";

    // Works
    JsonConvert.DeserializeObject<PC>(json).Dump();

    // Does not work unless you uncomment the parameterless constructor
    // or add a `Name` property to the above json.
    JsonConvert.DeserializeObject<PC>(json, new UserConverter()).Dump();
}

public class PC
{
    public User User { get; set; }
}

public class User
{
    public User(string name) { }

    //public User() {}

    public int Age { get; set; }
}

我用来解析类型的自定义转换器是这样实现的:

public class UserConverter : JsonConverter<User>
{
    public override void WriteJson(JsonWriter writer, User value, JsonSerializer serializer)
    {
        // I don't need it so it's not implemented.
        throw new NotImplementedException();
    }

    public override User ReadJson(JsonReader reader, Type objectType, User existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var jToken = JToken.Load(reader);
        existingValue = existingValue ?? (User)serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
        serializer.Populate(jToken.CreateReader(), existingValue);
        return existingValue;
    }
}

0 个答案:

没有答案