我需要Asp.net用特定的派生类反序列化对象的属性。
根据Newtonsoft的文档,我应该能够更改基类Equipment.Shared.Model.SimCard的JsonContract。https://www.newtonsoft.com/json/help/html/ContractResolver.htm
Class Transmitter有一个属性(Simcard(Equipment.Shared.Model.Simcard,但我需要将其反序列化为TlsModel.Simcard。否则,在反序列化过程中会丢弃T1sModel.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 is updated",所以我的合同反序列化器被考虑在内。
但发射机。SimCard仍然是设备。共享。模型。SimCard,而不是我排除的 TlsModel.SimCard我错过什么了吗?
还必须用适当的创建函数替换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<Equipment.Shared.Model.SimCard>
,其Create()
方法返回new SimCard()
。public class SimCardConverter : CustomCreationConverter<Equipment.Shared.Model.SimCard> { public override bool CanConvert(Type objectType) { return typeof(Equipment.Shared.Model.SimCard) == objectType; } public override Equipment.Shared.Model.SimCard Create(Type objectType) { return new SimCard(); } }
(如果直接反序列化任何派生类型的
Equipment.Shared.Model.SimCard
,则可能还需要重写CustomCreationConverter<T>.CanConvert(Type objectType)
以返回typeof(T) == objectType;
而不是typeof(T).IsAssignableFrom(objectType);
。(
在这里演示小提琴。
如果您使用的是newtonsoft json,您可以通过使用(在序列化和反序列化类型下(类型名称处理来完成,如下所述:https://www.newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm
它只是添加了属性"@类型";到每个对象。
示例
考虑以下类别:
//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
});