我需要Asp.net来用特定的派生类反序列化对象的属性。
根据Newtonsoft的文档,我应该能够更改基类JsonContract的Equipment.Shared.Model.SimCard。https://www.newtonsoft.com/json/help/html/ContractResolver.htm
类发送器有一个属性(Simcard) Equipment.Shared.Model.SimCard,但是我需要将它反序列化为TlsModel.SimCard,否则在反序列化过程中会丢弃TlsModel.SimCard属性。
public class TlsModelContractResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
JsonContract contract = base.CreateContract(objectType);
if (objectType == typeof(Equipment.Shared.Model.SimCard) )
{
contract.CreatedType = typeof(SimCard);
Console.WriteLine("Simcard CreateType is updated");
}
return contract;
}
}在第一次反序列化时,我有日志行'Simcard CreateType是更新‘,所以我的合同沙漠被考虑在内。
但transmitter.SimCard仍然是一个Equipment.Shared.Model.SimCard,而不是Equipment.Shared.Model.SimCard,正如我所强调的那样。
我错过了什么吗?
发布于 2020-07-08 20:35:29
还必须用适当的创建函数替换JsonContract.DefaultCreator的值,如果基类没有公共构造函数,则可能设置JsonContract.DefaultCreatorNonPublic = false:
public class TlsModelContractResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
JsonContract contract = base.CreateContract(objectType);
if (objectType == typeof(Equipment.Shared.Model.SimCard) )
{
contract.CreatedType = typeof(SimCard);
Debug.WriteLine("Simcard CreateType is updated");
contract.DefaultCreator = () => new SimCard();
contract.DefaultCreatorNonPublic = false;
}
return contract;
}
}备注:
DefaultContractResolver.CreateContract()后,契约将完全初始化,因此您将需要手动进行任何和所有更改。SimCard模型具有参数化构造函数,则需要重写DefaultContractResolver.CreateObjectContract并更新CreatorParameters和OverrideCreator。SimCardConverter : CustomCreationConverter,它的Create()方法返回一个new SimCard()。
公共类SimCardConverter :SimCardConverter{公共覆盖bool CanConvert(类型objectType) {返回类型( Equipment.Shared.Model.SimCard ) == objectType;}公共重写Equipment.Shared.Model.SimCard创建(objectType类型){返回新SimCard();}}
(如果您曾经直接反序列化任何派生类型的CustomCreationConverter.CanConvert(Type objectType),则还可能需要重写typeof(T) == objectType;而不是typeof(T).IsAssignableFrom(objectType);。)演示小提琴这里。
发布于 2020-07-08 18:49:29
如果使用newtonsoft,可以使用(在序列化和反序列化类型下)类型名称处理(如下面所解释的:https://www.newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm )。
它只是将属性"@type“添加到每个对象。
示例
请考虑以下课程:
//dll My.Dll
namespace My.Namespace
public class MyObj {
public string Name {get;set;}
public object Whatever {get;set;}
}
var objInner = new MyObj { Name = "Inner" };
var objOuter = new MyObj { Name = "Outer", Whatever = obj1 }
var jsonString = JsonConvert.SerializeObject(objOuter, Formatting.Indented, new
JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});
Console.Writeline(jsonString);
//produces
//{
// "@type": "My.Namespace.MyObj, My.Dll",
// "Name": "Outer",
// "Whatever": {
// "@type": "My.Namespace.MyObj, My.Dll",
// "Name": "Inner"
// }
//}
//to deserialize
var deserializedObj = JsonConvert.DserializeObject<MyObj>(objOuter, new
JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});https://stackoverflow.com/questions/62800996
复制相似问题