下面是序列化 ChatResponseMessage 的代码
var message = AzureOpenAIModelFactory.ChatResponseMessage(ChatRole.Assistant, "OK"); var json = JsonSerializer.Serialize( message, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true }); Console.WriteLine(json);
输出的 json 却丢了 role 属性(类型是 ChatRole)的值
role
ChatRole
{ "role": {}, "content": "OK", "toolCalls": [], "functionCall": null, "azureExtensionsContext": null }
请问如何解决这个问题?
问题补充:Console.WriteLine(message.Role); 的输出是 assistant
Console.WriteLine(message.Role);
assistant
在C#中,当序列化枚举类型时,有时候会出现只序列化枚举的名称而不是其实际值的情况。这可能是由于默认的 JsonSerializer 在处理枚举类型时,将其转换为对象形式 {},而不是预期的字符串值。要解决这个问题,可以通过自定义 JsonConverter 来确保枚举值被正确地序列化为字符串。
JsonSerializer
{}
JsonConverter
首先,你需要创建一个继承自 JsonConverter 的类,用于处理 ChatRole 枚举的序列化。
```csharp using System; using System.Text.Json; using System.Text.Json.Serialization;
public class ChatRoleConverter : JsonConverter { public override ChatRole Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 如果需要反序列化,可以实现 Read 方法 throw new NotImplementedException(); }
public override void Write(Utf8JsonWriter writer, ChatRole value, JsonSerializerOptions options) { // 将 ChatRole 枚举值序列化为其字符串表示 writer.WriteStringValue(value.ToString().ToLower()); // 将枚举值转换为小写字符串输出 }
} ```
Read
Write 方法负责将 ChatRole 枚举值写入 JSON 中。
Write
应用枚举转换器:
在 JsonSerializerOptions 中注册你创建的枚举转换器。
JsonSerializerOptions
```csharp var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true }; options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)); // 添加枚举转换器
var json = JsonSerializer.Serialize(message, options); Console.WriteLine(json); ```
JsonStringEnumConverter 是 .NET Core 3.0+ 提供的一个内置转换器,用于将枚举值转换为字符串形式。
JsonStringEnumConverter
输出结果:
现在,重新运行你的代码,你应该会看到 role 属性被正确地序列化为字符串形式的枚举值。
json { "role": "assistant", "content": "OK", "toolCalls": [], "functionCall": null, "azureExtensionsContext": null }
通过以上步骤,你可以确保 ChatRole 枚举在序列化为 JSON 时,会以其字符串形式(例如 "assistant")而不是对象形式进行输出。这样就能保留枚举值的实际含义,而不是仅仅将其序列化为默认的对象形式。
"assistant"