小能豆

Azure.AI.OpenAI.ChatResponseMessage json 序列化问题

javascript

下面是序列化 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": {},
  "content": "OK",
  "toolCalls": [],
  "functionCall": null,
  "azureExtensionsContext": null
}

请问如何解决这个问题?

问题补充:Console.WriteLine(message.Role); 的输出是 assistant


阅读 57

收藏
2024-06-17

共1个答案

小能豆

在C#中,当序列化枚举类型时,有时候会出现只序列化枚举的名称而不是其实际值的情况。这可能是由于默认的 JsonSerializer 在处理枚举类型时,将其转换为对象形式 {},而不是预期的字符串值。要解决这个问题,可以通过自定义 JsonConverter 来确保枚举值被正确地序列化为字符串。

解决方法:使用自定义的 JsonConverter

  1. 创建枚举转换器类

首先,你需要创建一个继承自 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 中。

  • 应用枚举转换器

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+ 提供的一个内置转换器,用于将枚举值转换为字符串形式。

  • 输出结果

现在,重新运行你的代码,你应该会看到 role 属性被正确地序列化为字符串形式的枚举值。

json { "role": "assistant", "content": "OK", "toolCalls": [], "functionCall": null, "azureExtensionsContext": null }

通过以上步骤,你可以确保 ChatRole 枚举在序列化为 JSON 时,会以其字符串形式(例如 "assistant")而不是对象形式进行输出。这样就能保留枚举值的实际含义,而不是仅仅将其序列化为默认的对象形式。

2024-06-17