バージョン 7.0.1 Beta3 を使用して、抽象クラスの配列であるプロパティを持つ複雑な POCO をシリアル化/逆シリアル化しようとしています。これらの配列には、抽象クラスから派生したクラスのインスタンスが含まれている可能性があります。
シリアル化では、すべて正常に行われているようです。以下の Json フラグメントは、型情報が正しく設定されていることを示しています。
Json フラグメント:
"Items":
[
{
"$type": "IVXB_TS, ...",
"inclusive": true,
"value": "20091231"
}
]
しかし、デシリアライゼーションは次のエラーで失敗します。
QTY 型のインスタンスを作成できませんでした。型はインターフェイスまたは抽象クラスであるため、インスタンス化できません。
クラス階層は次のとおりです。
[System.Xml.Serialization.XmlIncludeAttribute(typeof(IVXB_TS))]
public abstract partial class ANY : object, System.ComponentModel.INotifyPropertyChanged
{
}
[System.Xml.Serialization.XmlIncludeAttribute(typeof(IVXB_TS))]
public abstract partial class QTY : ANY
{
}
[System.Xml.Serialization.XmlIncludeAttribute(typeof(IVXB_TS))]
public partial class TS : QTY
{
}
public partial class IVXB_TS : TS
{
}
アイテムプロパティ:
[System.Xml.Serialization.XmlElementAttribute("high", typeof(IVXB_TS))]
[System.Xml.Serialization.XmlElementAttribute("low", typeof(IVXB_TS))]
public QTY[] Items
Json フラグメント内の型情報は使用されていないようです。これはデシリアライゼーション構成の問題でしょうか?
ベストアンサー1
この問題の解決策は、デシリアライザを次のように設定することです。jsonの型情報を使用するデフォルトでは使用されません。
シリアル化は次のように行われます。
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
serializer.Converters.Add(new Newtonsoft.Json.Converters.JavaScriptDateTimeConverter());
serializer.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
serializer.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto;
serializer.Formatting = Newtonsoft.Json.Formatting.Indented;
using (StreamWriter sw = new StreamWriter(fileName))
using (Newtonsoft.Json.JsonWriter writer = new Newtonsoft.Json.JsonTextWriter(sw))
{
serializer.Serialize(writer, obj, typeof(MyDocumentType));
}
デシリアライズ時に、TypeNameHandling の設定を行う必要があります。
MyDocumentType obj = Newtonsoft.Json.JsonConvert.DeserializeObject<MyDocumentType>(File.ReadAllText(fileName), new Newtonsoft.Json.JsonSerializerSettings
{
TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto,
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
});