C# 在JsonContract中使用默认对象构造
当使用构造函数参数反序列化对象时,默认序列化程序可以对其中一些对象使用C# 在JsonContract中使用默认对象构造,c#,json.net,C#,Json.net,当使用构造函数参数反序列化对象时,默认序列化程序可以对其中一些对象使用null。但是,如果您想通过JsonContract并调用DefaultCreator创建对象,您将得到NullReferenceException 有没有一种方法可以对我用ResolveContract(..)解析的类型使用相同的实例化逻辑?我希望避免将无参数构造函数添加到我正在使用的所有受影响的类型中 这意味着,我希望我的自定义转换器能够通过为构造函数参数注入nulls来初始化对象,这些参数没有像第一次调用反序列化对象那样
null
。但是,如果您想通过JsonContract
并调用DefaultCreator
创建对象,您将得到NullReferenceException
有没有一种方法可以对我用ResolveContract(..)
解析的类型使用相同的实例化逻辑?我希望避免将无参数构造函数添加到我正在使用的所有受影响的类型中
这意味着,我希望我的自定义转换器能够通过为构造函数参数注入null
s来初始化对象,这些参数没有像第一次调用反序列化对象那样指定,也没有使用自定义转换器
我创建了这个小型概念验证演示,向您展示我的意思:
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; }
}
void Main()
{
var json=@”
{
“用户”:{
年龄:80
}
}";
//工作
JsonConvert.DeserializeObject(json.Dump();
//除非取消对无参数构造函数的注释,否则不起作用
//或者在上面的json中添加一个`Name`属性。
反序列化对象(json,new UserConverter()).Dump();
}
公营电脑
{
公共用户{get;set;}
}
公共类用户
{
公共用户(字符串名){}
//public User(){}
公共整数{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;
}
}
公共类UserConverter:JsonConverter
{
公共重写void WriteJson(JsonWriter编写器、用户值、JsonSerializer序列化器)
{
//我不需要它,所以它没有实现。
抛出新的NotImplementedException();
}
公共重写用户ReadJson(JsonReader阅读器,类型objectType,用户existingValue,bool hasExistingValue,JsonSerializer序列化程序)
{
var jToken=jToken.Load(读卡器);
existingValue=existingValue???(用户)序列化程序.ContractResolver.ResolveContract(objectType.DefaultCreator();
填充(jToken.CreateReader(),existingValue);
返回现有值;
}
}
Json.NET可以使用构造函数。但是这些类与JSON字符串不匹配。如果User
构造函数是public User(int-age){age=age;}
您将得到正确初始化的object@PanagiotisKanavos恐怕你可能没有抓住我问题的重点-(在我的实际用例中,哪个是?实际情况是什么?什么是$type
属性?您使用的代码中没有此类属性,示例演示了键入错误,而不是发布相关代码的实际问题。)example@PanagiotisKanavos您仍然缺少要点…要点是使用构造函数参数创建对象使用与第一次调用反序列化
方法相同的逻辑进行rs(无自定义转换器),这是为缺少的参数注入null
s。我删除了与此问题完全无关的段落…结果它太分散注意力了。@T3ch,我说了很好。没有理解。很抱歉英语不好。你制作了一个MCVE。问题很清楚。一定没有键入什么。Json.NET可以使用constru但是类与JSON字符串不匹配。如果User
构造函数是public User(int-age){age=age;}
则会返回正确初始化的object@PanagiotisKanavos恐怕你可能没有抓住我问题的重点-(在我的实际用例中,哪个是?实际情况是什么?什么是$type
属性?您使用的代码中没有此类属性,示例演示了键入错误,而不是发布相关代码的实际问题。)example@PanagiotisKanavos您仍然缺少要点…要点是使用构造函数参数创建对象使用与第一次调用反序列化
方法相同的逻辑进行rs(无自定义转换器),这是为缺少的参数注入null
s。我删除了与此问题完全无关的段落…它太分散注意力了。@T3ch,我说了很好。理解错误。很抱歉英文不好。你制作了一个MCVE。问题很清楚。一定是打错了什么。