今天在使用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
