さまざまなタイプと継承を持つ、ネストされた .net クラスのセットがあります。アイテムの行コレクションを模倣しようとします。クラスの 1 つは、オブジェクト型の Value プロパティを含む Cell クラスです (ここには、他のネストされたセルまたは行であっても、何でも入れることができます)。Cell および Row クラスは、基本 ItemComponent クラスから継承します (複合パターン)
これをサポートするカスタム コンバーターを作成しました。TypeNameHandling を All に使用した後、正しいオブジェクト タイプに逆シリアル化されます。
私が抱えている問題は、ネストされたセルにあります。別のセルまたは行である値を持つ Cell がある場合、値を入力するシリアライザーの代わりに、それを表す文字列を Value プロパティに取得します。これまでの私のコードは次のとおりです
public static object FromJson<T>(this string obj, T outputType)
{
return JsonConvert.DeserializeObject(obj, outputType as Type, new JsonConverter[1] { new ItemComponentJsonConverter() });
}
public abstract class CustomJsonConverterBase<T> : JsonConverter
{
protected abstract T Create(Type objectType, JObject jsonObject);
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jsonObject = JObject.Load(reader);
var typeName = Type.GetType(jsonObject["$type"].ToString().Substring(0, jsonObject["$type"].ToString().IndexOf(',')));
var target = Create(typeName ?? objectType, jsonObject);
serializer.Populate(jsonObject.CreateReader(), target);
// this is my attempt to make it work, but it doesn't. on first iteration it's populated, then I get a JObject with text again, and again
if (target is Cell && (target as Cell).Value is JArray)
{
var innerCell = (target as Cell).Value.ToString().Substring(1, (target as Cell).Value.ToString().Length - 2).FromJson(typeof(Cell));
(target as Cell).Value = innerCell;
}
return target;
}
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
}
public class ItemComponentJsonConverter : CustomJsonConverterBase<ItemComponent>
{
protected override ItemComponent Create(Type objectType, JObject jsonObject)
{
if (objectType == typeof(Row))
{
return new Row();
}
if (objectType == typeof(Entity))
{
return new Entity();
}
if (objectType == typeof(Cell))
{
return new Cell();
}
return (ItemComponent)Activator.CreateInstance(objectType);
}
}
基本的に、私はこのようなものを手に入れたら(私はそれを短くしました)、正しい構造を得たいと思っています
セル .Value -> エンティティ .childItems 行 .childItems セル .Value -> 124
等々
{
"$type": "Arda.Lib.Models.Core.Cell, Arda.Lib",
"childItems": {
"$type": "System.Collections.Generic.List`1[[Arda.Lib.Models.Core.ItemComponent, Arda.Lib]], mscorlib",
"$values": []
},
"Value": {
"$type": "Arda.Lib.Models.Core.Entity, Arda.Lib",
"childItems": {
"$type": "System.Collections.Generic.List`1[[Arda.Lib.Models.Core.ItemComponent, Arda.Lib]], mscorlib",
"$values": [
{
"$type": "Arda.Lib.Models.Core.Row, Arda.Lib",
"childItems": {
"$type": "System.Collections.Generic.List`1[[Arda.Lib.Models.Core.ItemComponent, Arda.Lib]], mscorlib",
"$values": [
{
"$type": "Arda.Lib.Models.Core.Cell, Arda.Lib",
"childItems": {
"$type": "System.Collections.Generic.List`1[[Arda.Lib.Models.Core.ItemComponent, Arda.Lib]], mscorlib",
"$values": []
},
"Value": 124,
"Id": 247,