私の問題は、json オブジェクトを C# オブジェクトにデシリアライズしたいのですが、トリックは C# オブジェクトに List< abstract class > が含まれており、この抽象クラスが別の 10 クラスのスーパー クラスであることです。
public sealed class SearchAPIResult
{
public string Status;
public SearchAPIQuery Query;
public SearchResults Result;
public SearchAPIResult()
{
}
public SearchAPIResult(string status)
{
Status = status;
}
}
そしてSearchAPIResult
次のとおりです。
public sealed class SearchResults
{
public string TextAnswer;
public List<APIResultWidget> Items;
public SearchResults()
{
Items = new List<APIResultWidget>();
}
}
ここで、オブジェクトAPIResultWidget
は抽象クラスであり、そこから約 10 個のクラスが継承されます。
問題は、JSON オブジェクトに、デシリアライザーを 10 個の派生クラスのどのオブジェクトにキャストするかをガイドするための自動化されたもの (JSON.NET の typeNameHandling など) がないことです。代わりに、オブジェクトは次のように Type と SubType の 2 つのフィールドでマークされます。
{
"Status": "OK",
"Query": {
"Query": "this is a query",
"QueryLanguage": "EN"
},
"Result": {
"TextAnswer": "This is your text answer",
"Items": [{
"Type": "list",
"SubType": null,
"Title": null,
"Items": []
}, {
"Type": "text",
"Content": "this is some content"
}
]
}
}
前の json オブジェクトでは、Result リストに 2 つのオブジェクトが含まれています。
{
"Type": "list",
"SubType": null,
"Title": null,
"Items": []
}
これは listWidget 型のクラスにマップされます (abstractAPIResultWidget
と 2 つから継承します:
{
"Type": "text",
"Content": "this is some content"
}
textWidget
これは、同じ抽象クラスからも継承するクラスにマップされます
Json.NET の方法を使用する場合
SearchAPIResult converted = (SearchAPIResult)JsonConvert.DeserializeObject(json, typeof(SearchAPIResult), new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
次の例外がスローされます。
タイプ Kngine.API.APIResultWidget のインスタンスを作成できませんでした。型はインターフェイスまたは抽象クラスであり、インスタンス化できません。パス 'Result.Items[0].Type'、行 1、位置 136。
その型がフィールド Type と SubType の両方によって定義されていることを指摘し、コンバーターにそのカスタム型アノテーターを与えるカスタムの方法があると思いますが、そうですか?