今天在使用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 nowreturn true;}public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer){ //explicitly specify the concrete type we want to createreturn 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