如何使用特定的派生类反序列化对象的属性



我需要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并更新CreatorParametersOverrideCreator

  • 作为自定义合约解析器的替代方案,您可以引入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
});

最新更新