今天在使用 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);
- }
- }
方法三: 直接使用 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
来源: http://www.bubuko.com/infodetail-2931777.html