В соответствии с документацией System.Text.Json
:
Для сериализации свойств производного типа используйте один из следующих подходов:
- (...)
- Объявить сериализованный объект как
object
.
К сожалению, как я только что выяснил, это не позволяет сериализовать производные свойства членов списка. Рассмотрим следующие классы DTO:
public abstract class GameUpdate
{
public abstract string Type { get; }
}
public class ConsoleMessage : GameUpdate
{
public override string Type => "ConsoleMessage";
public string MessageContent { get; set; }
}
public class HitpointsUpdate : GameUpdate
{
public override string Type => "HitpointsUpdate";
public long MonsterID { get; set; }
public long NewHP { get; set; }
}
Они должны использоваться как List<GameUpdate>
. К сожалению, объявление списка для сериализации как object
все еще не может сериализовать важные свойства:
var gameUpdates = new List<GameUpdate>
{
new ConsoleMessage { MessageContent = "Chimzee lost 10 HP!"},
new HitpointsUpdate { MonsterID = 5, NewHP = 90 }
};
var json = System.Text.Json.JsonSerializer.Serialize<object>(gameUpdates);
Console.WriteLine(json);
Это приводит к следующему JSON:
[{"Type":"ConsoleMessage"},{"Type":"HitpointsUpdate"}]
Для сравнения, используя Newtonsoft.Json.JsonConvert.SerializeObject(gameUpdates)
дает следующий результат:
[{"Type":"ConsoleMessage","MessageContent":"Chimzee lost 10 HP!"},{"Type":"HitpointsUpdate","MonsterID":5,"NewHP":90}]
Можно ли добиться аналогичных результатов, используя System.Text.Json
?
Почему я спрашиваю это: я постоянно пытаюсь разработать браузерную игру в качестве хобби-проекта, и именно так я реализовал взаимодействие сервера с браузером. С выходом Asp. NET Core 3 его документация поощряет переход с Newtonsoft. JSON на System.Text. Json. Прочитав в документации, что сериализация polymorphi c возможна, я удалил код, связанный с Newtonsoft, и начал использовать System.Text. Json, только чтобы узнать, что игра больше не работает.