带有枚举的抽象类无法正确序列化

问题描述 投票:0回答:1

我的项目中有以下代码

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

c# oop inheritance serialization enums
1个回答
0
投票

由于

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
值序列化为字符串。

© www.soinside.com 2019 - 2024. All rights reserved.