我的项目中有以下代码
GameEngine
using System.Text.Json;
using Domain;
namespace GameEngine;
public class Game
{
public GameState State = new();
private static readonly JsonSerializerOptions JsonOptions = new()
{
IncludeFields = true,
WriteIndented = true
};
private void SaveGame(string fileName)
{
var jsonString = JsonSerializer.Serialize(State, JsonOptions);
var exeFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
var workPath = Path.GetDirectoryName(exeFilePath);
if (workPath == null) return;
var saveFilePath = Path.Combine(workPath, fileName) + ".json";
File.WriteAllText(saveFilePath, jsonString);
}
}
以及项目中的以下内容
Domain
using System.Text.Json.Serialization;
namespace Domain;
public class GameState
{
public List<Player> PlayerList { get; set; } = default!;
}
[JsonDerivedType(typeof(AIPlayer), typeDiscriminator: "aiPlayer")]
[JsonDerivedType(typeof(HumanPlayer), typeDiscriminator: "humanPlayer")]
public abstract class Player
{
public Hand Hand { get; } = new();
}
public class Hand
{
public List<Card> CardList { get; set; } = [];
}
[JsonDerivedType(typeof(BlackCard), typeDiscriminator: "blackCard")]
[JsonDerivedType(typeof(ColoredCard), typeDiscriminator: "coloredCard")]
public abstract class Card
{
public Enum Value { get; set; } = default!;
}
public class BlackCard : Card
{
public BlackCard(EBlackCardValue value)
{
Value = value;
}
}
public class ColoredCard : Card
{
public ColoredCard(EColoredCardValue value)
{
Value = value;
}
}
public enum EBlackCardValue
{
Wild,
Joker
}
public enum EColoredCardValue
{
One,
Two,
Three
}
如何序列化
GameState
的实例,并正确序列化和反序列化卡值?目前我只得到以下内容
{
"PlayerList": [
{
"$type": "humanPlayer",
"Hand": {
"CardList": [
{
"$type": "blackCard",
"Value": {},
},
{
"$type": "blackCard",
"Value": {},
},
...
我不想切换到 JSON.Net,只想切换到 System.Text.Json
由于
Value
类中的 Card
是 Enum
,JSON 序列化器会将值序列化为对象。当您添加 JsonStringEnumConverter
转换器时,您会收到错误,因为它无法从 Enum
类型进行序列化。
这可以通过在派生类中声明具有特定枚举类型的
Value
属性来解决,如下所示:
public class BlackCard : Card
{
[JsonConverter(typeof(JsonStringEnumConverter))]
public EBlackCardValue Value { get; set; } = default!;
public BlackCard(EBlackCardValue value)
{
Value = value;
}
}
这将从抽象类中隐藏继承的成员:
Card
但这很可能不是您正在寻找的答案。
在这种情况下,我相信您需要实现一个自定义 JSON 转换器来序列化
Enum
类型:
public class CustomEnumConverter : JsonConverter<Enum>
{
public override Enum Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options) =>
throw new Exception("Deserialize is not supported!");
public override void Write(
Utf8JsonWriter writer,
Enum value,
JsonSerializerOptions options) =>
writer.WriteStringValue(value.ToString());
}
并在上面应用已实现的自定义 JSON 转换器的
JsonConverter
属性:
[JsonDerivedType(typeof(BlackCard), typeDiscriminator: "blackCard")]
[JsonDerivedType(typeof(ColoredCard), typeDiscriminator: "coloredCard")]
public abstract class Card
{
[JsonConverter(typeof(CustomEnumConverter))]
public Enum Value { get; set; } = default!;
}
这将允许将
Enum
值序列化为字符串。