无法从 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"}
}
我正在使用 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 jsonvar 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"}
}