如何为 Swagger 示例类配置 Newtonsoft JSON.NET 序列化器设置?

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

我在实现 REST API 的 ASP.NET Core (.NET 8) 项目中使用 Newtonsoft JSON.NET 进行对象序列化,并且我需要从其他地方使用的序列化设置更改用于 Swagger 示例的序列化设置,但我没有看到任何方法仅为 Swagger UI 自定义序列化设置。可以吗?如果可以的话,有没有例子?

这是我正在寻找的背景信息和一些细节。

我们使用 JSON.NET,因为它在处理我们无法控制的数据时更加宽容。例如,我们可以在其中一项外部服务中返回错误详细信息,并在字符串属性中嵌入非转义换行符,这违反了 JSON 规范。这不是我们的代码,因此我们无法修复它,并且 Microsoft 的 JSON 序列化无法处理它,而 JSON.NET 可以。所以,我们现在必须使用它。

当我们为 JSON 配置 MVC 设置时,我们使用以下选项:

builder.Services
  .AddControllers()
  .AddNewtonsoftJson
  (
    options =>
    {
      options.SerializerSettings.Converters.Add(new StringEnumConverter());
      options.SerializerSettings.NullValueHandling     = NullValueHandling.Ignore;
      options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
      options.SerializerSettings.DateFormatHandling    = DateFormatHandling.IsoDateFormat;

      // Do not change the following line or it may fail to serialize hierarchical data.
      options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
    }
  );

这工作得很好,只是当 Swagger UI 显示预期传递给 POST/PATCH 方法的输入对象的示例时,这些对象包含

$id
属性,这会让读者感到困惑。例如,如果我有一个像这样的对象:

public class GroupRequestCreateExample: IExamplesProvider<Group>
{
  public Group GetExamples()
  {
    Group group = new()
    {
      DisplayName = "Fonzie Fans",
      Description = "Everyone who likes Fonzie."
    };

    return group;
  }
}

Swagger 示例将显示为:

{
  "$id":"1",
  "displayName":"Fonzie Fans",
  "description": "Everyone who likes Fonzie."
}

我希望它看起来像:

{
  "displayName":"Fonzie Fans",
  "description": "Everyone who likes Fonzie."
}

我了解如何在全局范围内关闭显示

$id
属性,但如果这样做,它会中断从外部服务接收分层数据的调用,因此我需要为除 Swagger 示例之外的所有内容保留
options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects
设置。

可以吗?

asp.net-core json.net swagger-ui swashbuckle swashbuckle.aspnetcore
1个回答
0
投票

您可以自定义

ISchemaFilter
,例如如下所示:

public class CustomSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type == typeof(Group))
        {
            var groupExample = new GroupRequestCreateExample().GetExamples();

            // Customize the JSON serialization settings here
            var settings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                DateFormatHandling = DateFormatHandling.IsoDateFormat,
                PreserveReferencesHandling = PreserveReferencesHandling.None
            };

            var exampleJson = JsonConvert.SerializeObject(groupExample, settings);
            schema.Example = new OpenApiString(exampleJson);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.