今天在使用JSON序列化类时出现问题,原来类中有一个接口,在反序列化时不知道接口的实体是什么
public class Device : IComparer
{
private string _deviceid;
private string _devicename;
private string _deviceaddr = "01";
private string _friendlyname;
private string _devdescription;
private IBus _CommBus;
/// <summary>
/// 通信接口
/// </summary>
public IBus BusConnector
{
get { return _CommBus; }
set { _CommBus = value; }
}
/// <summary>
/// 设备编号-唯一性
/// </summary>
public string DeviceId
{
set { _deviceid = value; }
get { return _deviceid; }
}
/// <summary>
/// 设备名称
/// </summary>
public string DeviceName
{
set { _devicename = value; }
get { return _devicename; }
}
/// <summary>
/// 设备通信地址
/// </summary>
public string DeviceAddr
{
set { _deviceaddr = value; }
get { return _deviceaddr; }
}
/// <summary>
/// 发送指令到设备
/// </summary>
/// <param name="send"></param>
public virtual bool SendCmd(byte[] sendbytes)
{
return true;
}
public virtual bool DevOpen()
{
return _CommBus.Open();
}
#region 实现IComparer接口,按设备ID排序
public int Compare(object x, object y)
{
if ((x is Device) && (y is Device))
{
Device a = (Device)x;
Device b = (Device)y;
return a._deviceid.CompareTo(b._deviceid);
}
return 0;
}
#endregion End
}
Device类中,BusConnector为一通信接口,根据需要传入不同的通信方式实体,,正常反序列化时出现
“Type is an interface or abstract class and cannot be instantiated” 这样的错误
方法一:在序列化时增加对应的说明
var settings = new JsonSerializerSettings(); settings.TypeNameHandling = TypeNameHandling.Objects; JsonConvert.SerializeObject(entity, Formatting.Indented, settings);
方法二:增加转化类
public class Model { [JsonConverter(typeof(ConcreteTypeConverter<Something>))] public ISomething TheThing { get; set; } }
public class ConcreteTypeConverter<TConcrete> : JsonConverter { public override bool CanConvert(Type objectType) { //assume we can convert to anything for now return true; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { //explicitly specify the concrete type we want to create return serializer.Deserialize<TConcrete>(reader); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { //use the default serialization - it works fine serializer.Serialize(writer, value); } } public class ConcreteTypeConverter<TConcrete> : JsonConverter { public override bool CanConvert(Type objectType) { //assume we can convert to anything for now return true; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { //explicitly specify the concrete type we want to create return serializer.Deserialize<TConcrete>(reader); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { //use the default serialization - it works fine serializer.Serialize(writer, value); } }
方法三:直接使用JSON.NET上的在属性上增加
[JsonProperty(TypeNameHandling = TypeNameHandling.Auto)]
/// <summary>
/// 通信接口
/// </summary>
public IBus BusConnector
{
get { return _CommBus; }
set { _CommBus = value; }
}
这三种方法者有可实现性,其中方法三最方便,方法一可以实现,但每个对象之前增加对象类型。
解决方法参考:https://stackoverflow.com/questions/2254872/using-json-net-converters-to-deserialize-properties
https://stackoverflow.com/questions/8030538/how-to-implement-custom-jsonconverter-in-json-net-to-deserialize-a-list-of-base/8031283#8031283
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix