无法从 C# 代码生成枚举到 json 字符串

Unable to produce enum from c# code to json string

我正在使用 JsonForm 在我的 MVC 核心 Web 应用程序中生成动态表单。我在我的视图模型中的以下代码中使用 System.Text.Json.JsonSerializer.Serialize 来生成一个简单的单字段表单。我的目标是最终将此 json 存储在数据库中并从那里检索它。

 public TestsViewModel GetFormControls1()
        {
            var myJsonModel = new
            {
                schema = new
                {
                    client = new
                    {
                        type = "object",
                        title = "Client",
                        properties = new
                        {
                            forename = new
                            {
                                type = "string",
                                title = "Forename",
                                minLength = 3,
                                maxLength = 10,
                            }
                        }
                    }
                },
                form = new List<Object>
                {
                    new {
                        key = "client.forename",
                        title = "Forename"
                    }
                },
                value = new
                {
                    client = new
                    {
                        forename = "",
                    }
                }
            };

            TestsViewModel homeVm = new TestsViewModel();
            homeVm.FormControls = System.Text.Json.JsonSerializer.Serialize(myJsonModel);
            return homeVm;
        }

以上代码工作正常并生成以下 json 模式,然后用于创建表单。

{
  "schema": {
    "client": {
      "type": "object",
      "title": "Client",
      "properties": {
        "forename": {
          "type": "string",
          "title": "Forename",
          "minLength": 3,
          "maxLength": 10
        }
      }
    }
  },
  "form": [
    {
      "key": "client.forename",
      "title": "Forename"
    }
  ],
  "value": {
    "client": {
      "forename": ""
    }
  }
}

我现在需要为我的 json 生成一个枚举,以便在表单中显示用于选择性别的下拉列表。但是,我无法通过 c# 代码做到这一点。有人可以帮忙吗?我希望我的 c# 代码生成以下 json(请注意模式和表单中的两个性别条目)。

{
  "schema": {
    "client": {
      "type": "object",
      "title": "Client",
      "properties": {
        "forename": {
          "type": "string",
          "title": "Forename",
          "minLength": 3,
          "maxLength": 10
        },
        "gender": {
          "type": "string",
          "title": "Gender",
          "enum": [
            "male",
            "female",
            "alien"
          ]
        }
      }
    }
  },
  "form": [
    {
      "key": "client.forename",
      "title": "Forename"
    },
    {
      "key": "client.gender",
      "titleMap": {
        "male": "Dude",
        "female": "Dudette",
        "alien": "I'm from outer space!"
      }
    }
  ],
  "value": {
    "client": {
      "forename": ""
    }
  }
}

我试过使用下面的代码,但是 enum 是 c# 中的一个关键字,所以我得到了错误。

gender = new
                            {
                                type = "string",
                                title = "Gender",
                                enum = "[male, female, alien]"
                            }

同时 Enum = "[male, female, alien]" 生成 "Enum": "[male, female, alien]" 而不是 "enum": [ "male", "female", "alien" ]

我有一个性别查找 table,我最终会用它来以某种方式生成上面的枚举,所以任何关于它的想法也会有所帮助。

更新 @dbc 的评论为我的大部分问题提供了解决方案。但是,如果我尝试将字符串映射到 int.

,我仍在努力生成 titleMap json
var gender3 = new
            {
                type = "string",
                title = "Gender",
                titleMap = new List<string> { new string("1" + ":" + "Male"), new string("2" + ":" + "Female")}
            };

以上代码产生

{
  "type": "string",
  "title": "Gender",
  "titleMap": [
    "1:Male",
    "2:Female"
  ]
}

但是,我需要 1 和 Male 在 { } 内用它们自己的双引号代替 [ ],如下所示。

{
  "type": "string",
  "title": "Gender",
  "titleMap": {
    "1": "Male",
    "2": "Female"
  }
}

据我了解,您正试图将枚举值数组作为它们的文本名称序列化到 JSON 中。最简单的解决方案是将一个数组或枚举列表 属性 添加到您的 TestViewModel 并使用 JsonStringEnumConverter 转换器将它们序列化为字符串而不是数字。

这里有一个示例,说明如何实现您的目标。

假设您有一些具有一组值的枚举:

//This is an arbitrary enum, this could be 'Gender', in your case
public enum TestEnum
{
    value1,
    value2,
    value3,
    value4,
}

并且您想写下这些枚举值的数组。将枚举列表 属性 (或枚举数组)添加到您的模型。如果您希望 JSON 中的 属性 名称成为保留字之一(如 enum),要么使用 JsonPropertyName 属性覆盖名称(并保留名称以编程方式最有意义):

public class TestsViewModel_Option1
{
    // In your case, this property could be called 'Genders' to be self-documenting
    [JsonPropertyName("enum")]
    public List<TestEnum> ListOfEnums { get; set; }
}

或者,如果您确实希望 属性 名称成为保留关键字并且不希望 to/can 由于某种原因不使用该属性,请使用 @ 符号。

public class TestsViewModel_Option2
{
    // Or use fixed-size array, TestEnum[], if needed
    public List<TestEnum> @enum { get; set; }
}

现在你的代码是这样的 JsonSerializer:

private static void SerializeListOfEnums()
{
    var model1 = new TestsViewModel_Option1
    {
        ListOfEnums = { TestEnum.value1, TestEnum.value3 }
    };

    var options = new JsonSerializerOptions
    {
        Converters = { new JsonStringEnumConverter() }
    };

    // {"enum":["value1","value3"]}
    Console.WriteLine(JsonSerializer.Serialize(model1, options));

    var model2 = new TestsViewModel_Option2
    {
        @enum = { TestEnum.value1, TestEnum.value3 }
    };

    // {"enum":["value1","value3"]}
    Console.WriteLine(JsonSerializer.Serialize(model2, options));
}

enum 是 C# 中的一个关键字,所以你需要在 enum 前面加上@

gender = new
                            {
                                type = "string",
                                title = "Gender",
                                @enum = new string[3]{"male", "female", "alien"}
                            }