如何在 ASP.NET Core 中正确设置 Swagger 示例?

发布于 2025-01-10 23:19:30 字数 3358 浏览 0 评论 0 原文

我的目标

仅在我使用 SwaggerRequestExample 注释的端点上正确设置 OpenApi JSON 文档中的请求示例,而不是端点响应或缺少此属性的其他端点。

预期结果:

"post": {
    "tags": [
      "Address"
    ],
    "requestBody": {
      "content": {
        },
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Address"
          },
          "example": {"id":"995ace6e-33d5-4efd-860e-b653fef60dad","binaryAddress":246,"distance":123}
        }
        }
      }
    },
    "responses": {
      "200": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Address"
            }
          }
          }
        }
      }

实际结果:

"post": {
    "tags": [
      "Address"
    ],
    "requestBody": {
      "content": {
        },
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Address"
          },
          "example": {"id":"995ace6e-33d5-4efd-860e-b653fef60dad","binaryAddress":246,"distance":123}
        }
        }
      }
    },
    "responses": {
      "200": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Address"
            },
            "example": {"id":"a04c827c-5e29-4940-8bee-89f8e07af5a8","binaryAddress":246,"distance":123}
          }
          }
        }
      }

错误消息:

我没有遇到任何错误消息。

我尝试过的:

我尝试了几种启动和控制器属性配置来尝试获得预期的行为,但无法获得预期的结果。这是我期望工作的配置,但不幸的是不是:

Startup.cs snippet

services.AddSwaggerGen(options =>
{
    options.MapType<ushort>(() => OpenApiSchemaFactory.MapInteger(typeof(ushort)));
});
services.ConfigureOptions<ConfigureSwaggerOptions>(); // calls .SwaggerExamples()
services.AddSwaggerGenNewtonsoftSupport();
services.AddSwaggerExamples();
services.AddSwaggerExamplesFromAssemblyOf<AddressExample>();

AddressController.cs minus other endpoints

[ApiVersion("1.0")]
[ApiController]
[Route("api/v{api-version:apiVersion}/[controller]")]
public class AddressController : ControllerBase
{
    [HttpPost]
    [Ok(typeof(Address))]
    [BadRequest]
    [SwaggerRequestExample(typeof(Address), typeof(AddressExample))]
    public IActionResult AddAddress([FromBody] Address address)
    {
        return Ok(_service.AddAddress(address)); // The service is just a pass-through layer at the moment
    }
}

AddressExample.cs

public class AddressExample : IExamplesProvider<Address>
{
    public Address GetExamples()
    {
        return new Address
        {
            Id = Guid.NewGuid(),
            BinaryAddress = 246L,
            Distance = 123
        };
    }
}

基于上面的代码,我只期望设置请求示例。但是,响应示例也已设置。对我来说更令人费解的是,不仅如此,在请求或响应中使用地址模型的任何端点也都设置了示例。

在我尝试正确配置它时,我发现这一行

services.AddSwaggerExamplesFromAssemblyOf<AddressExample>();

正在地址模型的所有实例中设置定义的示例,即使我不使用控制器端点上注释的 SwaggerRequestExample 属性。

目前,我不知道如何正确设置开箱即用的 swagger 配置示例,而无需为使用相关模型的每个实例创建示例。

有人可以指出我正确的方向或提供一个应该有效的例子吗?谢谢。

编辑:我也非常乐意提供额外的代码

My goal:

To correctly set the request examples in the OpenApi JSON document on only the endpoints I annotate with SwaggerRequestExample and not the endpoint response or other endpoints lacking this attribute.

Expected Result:

"post": {
    "tags": [
      "Address"
    ],
    "requestBody": {
      "content": {
        },
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Address"
          },
          "example": {"id":"995ace6e-33d5-4efd-860e-b653fef60dad","binaryAddress":246,"distance":123}
        }
        }
      }
    },
    "responses": {
      "200": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Address"
            }
          }
          }
        }
      }

Actual Result:

"post": {
    "tags": [
      "Address"
    ],
    "requestBody": {
      "content": {
        },
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Address"
          },
          "example": {"id":"995ace6e-33d5-4efd-860e-b653fef60dad","binaryAddress":246,"distance":123}
        }
        }
      }
    },
    "responses": {
      "200": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Address"
            },
            "example": {"id":"a04c827c-5e29-4940-8bee-89f8e07af5a8","binaryAddress":246,"distance":123}
          }
          }
        }
      }

Error Messages:

I haven't encountered any error messages.

What I've tried:

I've tried several startup and controller attribute configurations to try and get the expected behavior, but have been unable to get the expected result. This is the configuration I expect to work, but unfortunately is not:

Startup.cs snippet

services.AddSwaggerGen(options =>
{
    options.MapType<ushort>(() => OpenApiSchemaFactory.MapInteger(typeof(ushort)));
});
services.ConfigureOptions<ConfigureSwaggerOptions>(); // calls .SwaggerExamples()
services.AddSwaggerGenNewtonsoftSupport();
services.AddSwaggerExamples();
services.AddSwaggerExamplesFromAssemblyOf<AddressExample>();

AddressController.cs minus other endpoints

[ApiVersion("1.0")]
[ApiController]
[Route("api/v{api-version:apiVersion}/[controller]")]
public class AddressController : ControllerBase
{
    [HttpPost]
    [Ok(typeof(Address))]
    [BadRequest]
    [SwaggerRequestExample(typeof(Address), typeof(AddressExample))]
    public IActionResult AddAddress([FromBody] Address address)
    {
        return Ok(_service.AddAddress(address)); // The service is just a pass-through layer at the moment
    }
}

AddressExample.cs

public class AddressExample : IExamplesProvider<Address>
{
    public Address GetExamples()
    {
        return new Address
        {
            Id = Guid.NewGuid(),
            BinaryAddress = 246L,
            Distance = 123
        };
    }
}

Based on the above code, I'm only expecting the request example to be set. However, the response example is set too. Even more inexplicable to me is that not only that but any endpoint that uses the Address model in either the request or response has the example set as well.

In my attempt to configure this correctly, I discovered that this line

services.AddSwaggerExamplesFromAssemblyOf<AddressExample>();

Is setting the defined example in all instances of the address model even if I don't use the SwaggerRequestExample attribute annotated on my controller endpoint.

I'm currently at a loss as to how to set the examples with out of the box swagger configuration correctly without creating an example for every instance that the model in question is used.

Can someone point me in the right direction or provide an example that should work? Thanks.

Edit: I will be more than happy to provide additional code as well

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寻找我们的幸福 2025-01-17 23:19:30

我也想知道这个问题,所以我深入研究了 Swashbuckle 的文档。事实证明,这是通过 XML 文档注释来处理的。不久前,这感觉非常笨拙。首先,您必须向 API 方法添加 XML 文档注释。我的看起来像这样:

在此处输入图像描述

然后,您需要在项目的属性中打开 XML 文档文件生成:

在此处输入图像描述

我的测试项目名为 XcExample.Api.Sometext.因为我将“文件路径”字段留空,所以在编译时,它在二进制文件旁边放置了一个名为 XcExample.Api.Sometext.xml 的文件。

然后,要将这些数据包含在 OAS3/Swagger 生成中,您可以在 Program.cs 中找到如下所示的行:
输入图片此处描述
然后将该文件添加到生成信息中,如下所示:

然后当你查看 Swagger UI 时,它看起来像这样:
输入图片此处描述

那么您的 OAS 文档路径部分如下所示:


"paths": {
    "/api/{id}/GetTogether/{word}/Concat": {
      "post": {
        "tags": [
          "Concat"
        ],
        "summary": "Get Some Text Together for a Party",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "word index",
            "required": true,
            "style": "simple",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 9987
          },
          {
            "name": "word",
            "in": "path",
            "description": "indexed word",
            "required": true,
            "style": "simple",
            "schema": {
              "minLength": 2,
              "type": "string"
            },
            "example": "orange"
          }
        ],
        "requestBody": {
          "description": "words and puncuation",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Sentence"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/Sentence"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/Sentence"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    }
}

示例代码位于我的 GitHub 上的 XcExample.Api.Sometext 项目

I wondered about this too, so I dove into the documentation for Swashbuckle. It turns out that this is handled via XML Doc comments. Not too long ago this felt very clunky. To start with, you must add XML Doc comments to your API Method. Mine looked like this:

enter image description here

Then, you need to turn XML Documentation file generation in the properties of your project:

enter image description here

My test project was called XcExample.Api.Sometext. Because I left the 'file path' field blank, when I compiled it placed a file named XcExample.Api.Sometext.xml next to the binaries.

Then to include this data in the OAS3/Swagger generation you find the line in your Program.cs that looks like this:
enter image description here
And you add the file to the generation information like the following:
enter image description here

Then when you look at the Swagger UI it looks like this:
enter image description here

Then your OAS doc path section looks like:


"paths": {
    "/api/{id}/GetTogether/{word}/Concat": {
      "post": {
        "tags": [
          "Concat"
        ],
        "summary": "Get Some Text Together for a Party",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "word index",
            "required": true,
            "style": "simple",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 9987
          },
          {
            "name": "word",
            "in": "path",
            "description": "indexed word",
            "required": true,
            "style": "simple",
            "schema": {
              "minLength": 2,
              "type": "string"
            },
            "example": "orange"
          }
        ],
        "requestBody": {
          "description": "words and puncuation",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Sentence"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/Sentence"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/Sentence"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    }
}

The example code is on my XcExample.Api.Sometext project on github.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文