C# JSON.NET自定义构造函数
作为这个问题的一个部分问题,我试图在反序列化期间调用自定义构造函数。我的简化类层次结构如下所示:C# JSON.NET自定义构造函数,c#,constructor,json.net,deserialization,converter,C#,Constructor,Json.net,Deserialization,Converter,作为这个问题的一个部分问题,我试图在反序列化期间调用自定义构造函数。我的简化类层次结构如下所示: public abstract class BusinessObjectBase { internal BusinessObjectBase(SerializationContext context) : base(context) { } } public abstract class EditableObjectBase : BusinessObject
public abstract class BusinessObjectBase
{
internal BusinessObjectBase(SerializationContext context)
: base(context)
{
}
}
public abstract class EditableObjectBase : BusinessObjectBase
{
protected EditableObjectBase(SerializationContext context)
: base(context)
{
}
}
public class EditableObjectCollection<TObject> : BusinessObjectBase, ICollection<TObject>, IList, INotifyCollectionChanged where TObject : BusinessObjectBase
{
protected EditableObjectCollection(SerializationContext context)
: base(context)
{
}
}
internal class BusinessObjectCreationConverter : JsonConverter
{
public override bool CanWrite
{
get
{
return false;
}
}
public override bool CanConvert(Type objectType)
{
return typeof(BusinessObjectBase).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
object result = null;
if (reader.TokenType != JsonToken.Null)
{
JObject jsonObject = JObject.Load(reader);
result = this.Create(objectType, jsonObject);
Verification.Assert<NullReferenceException>(result != null, "No Business Object created.");
serializer.Populate(jsonObject.CreateReader(), result);
}
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
}
public BusinessObjectBase Create(Type objectType, JObject jsonObject)
{
JToken token = jsonObject.SelectToken("$type");
var typeString = token.Value<string>();
Type type = Type.GetType(typeString);
var businessObject = type.CreateUsingDesrializationConstructor<BusinessObjectBase>();
businessObject.Initialize(true);
return businessObject;
}
}
如果我用集合初始化我的类
var collection = new EditableObjectCollection<TestEditableObject>(null);
var poco = new AnyPocoContainingBusinessObject { BusinessObject = collection };
我得到一个例外:
无法将JSON对象填充到类型“KS.Interfaces.Core.Entities.EditableObjectCollection`1[KS.Interfaces.Core.Entities.Tests.Unit.EditableObjectCollectionTests+TestEditableObject]”上。路径“$type”,第1行,位置47
在我的转换器的此代码行中:
serializer.Populate(jsonObject.CreateReader(), result);
有人能告诉我原因吗?我非常确定我创建了正确的类型,并且使用EditableObjectBase派生对象,一切都很好。只有收藏似乎不起作用
如有任何提示,我们将不胜感激
Carsten即使我还没有找到让转换器工作的方法,但在调试问题的过程中我学到了一件事: 转换器似乎应该返回仍然具有相同JsonToken值的对象。在我的例子中,原始对象的JsonToken是JsonToken.object,但是对于我的转换结果,正确的标记值应该是JsonToken.Array,但是读者仍然可以看到JsonToken.object。在这一点上,我停止了我的研究,因为我找到了一种更好的方法来调用我的自定义构造函数 我编写了自己的合同解析器:
internal class BusinessBaseContractResolver : DefaultContractResolver
{
public BusinessBaseContractResolver()
{
this.DefaultMembersSearchFlags |= BindingFlags.NonPublic;
}
public override JsonContract ResolveContract(Type type)
{
JsonContract contract = base.ResolveContract(type);
if (typeof(BusinessObjectBase).IsAssignableFrom(type))
{
contract.DefaultCreator = delegate
{
var businessObject = type.CreateUsingDeserializationConstructor<BusinessObjectBase>();
businessObject.Initialize(true);
return businessObject;
};
}
return contract;
}
}
内部类BusinessBaseContractResolver:DefaultContractResolver
{
public BusinessBaseContractResolver()
{
this.DefaultMembersSearchFlags |=BindingFlags.NonPublic;
}
公共重写JsonContract ResolveContract(类型)
{
JsonContract contract=base.ResolveContract(类型);
if(typeof(BusinessObjectBase).IsAssignableFrom(type))
{
contract.DefaultCreator=委托
{
var businessObject=type.CreateUsingDeserializationConstructor();
businessObject.Initialize(true);
返回业务对象;
};
}
退货合同;
}
}
我希望这对某人有帮助
致以最良好的祝愿,
卡斯滕
serializer.Populate(jsonObject.CreateReader(), result);
internal class BusinessBaseContractResolver : DefaultContractResolver
{
public BusinessBaseContractResolver()
{
this.DefaultMembersSearchFlags |= BindingFlags.NonPublic;
}
public override JsonContract ResolveContract(Type type)
{
JsonContract contract = base.ResolveContract(type);
if (typeof(BusinessObjectBase).IsAssignableFrom(type))
{
contract.DefaultCreator = delegate
{
var businessObject = type.CreateUsingDeserializationConstructor<BusinessObjectBase>();
businessObject.Initialize(true);
return businessObject;
};
}
return contract;
}
}