在我的 .Net 核心中将自定义序列化程序添加到 Swagger API

Add custom serializer to Swagger in my .Net core API

我正在使用 jsonapi.org, then I'm using the JsonApiSerializer 中的 JSONAPI 规范来完成 JSONAPI规范,所以我的响应和请求正文如下所示:

{    
    "data": {
    "type": "articles",
    "id": "stringId",
    "attributes": {
      "title": "JSON:API paints my bikeshed!"
    }
}

我有一个实体"Article" 它看起来像:

public class Article
{
     public string Id { get; set; }
     public string title { get; set; }
}

然后我尝试使用 Swashbuckle Swagger 来记录我的 API,但是在 Swagger UI 我的示例请求和响应正文如下所示:

{
     "id": "string",
     "title": "string"
}

I think swagger is ignoring the JsonApiSerializer, there is a way to change the default serializer for swagger and use my own serializer?

我的 Startup.cs 看起来像:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            this.Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc(
                    "v1",
                    new OpenApiInfo
                    {
                        Version = "v1",
                        Title = "HTT API",
                        Description = "HTT API provides methods to handle events",
                        Contact = new OpenApiContact
                        {
                            Name = "htt",
                            Email = "info@htt.com",
                        },
                    });

                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                c.IncludeXmlComments(xmlPath);
            });


            services.AddAPIDependencies(this.Configuration);
            services.AddControllers().AddNewtonsoftJson(
            options =>
            {
                var serializerSettings = new JsonApiSerializerSettings();
                options.SerializerSettings.ContractResolver = serializerSettings.ContractResolver;
                options.SerializerSettings.Converters.Add(new StringEnumConverter());
            });

            services.Configure<DatabaseSettings>(
            this.Configuration.GetSection(nameof(DatabaseSettings)));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "HTT API V1");
            });

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

您可以使用 Swashbuckle.AspNetCore.Filters.

生成示例 swagger 请求和响应

从其中一篇引用的博客文章复制的示例:

[Route(RouteTemplates.DeliveryOptionsSearchByAddress)]
[SwaggerRequestExample(typeof(DeliveryOptionsSearchModel), typeof(DeliveryOptionsSearchModelExample))]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(DeliveryOptionsModel), Description = "Delivery options for the country found and returned successfully")]
[SwaggerResponseExample(HttpStatusCode.OK, typeof(DeliveryOptionsModelExample))]
[SwaggerResponse(HttpStatusCode.BadRequest, Type = typeof(ErrorsModel), Description = "An invalid or missing input parameter will result in a bad request")]
[SwaggerResponse(HttpStatusCode.InternalServerError, Type = typeof(ErrorsModel), Description = "An unexpected error occurred, should not return sensitive information")]
public async Task<IHttpActionResult> DeliveryOptionsForAddress(DeliveryOptionsSearchModel search)
{

注意各种 *Example 模型的使用。每个这样的类型都应该实现 IExamplesProvider 并生成样本数据:

public class DeliveryOptionsSearchModelExample : IExamplesProvider
{
    public object GetExamples()
    {
        return new DeliveryOptionsSearchModel
        {
            Lang = "en-GB",
            Currency = "GBP",
            Address = new AddressModel
            {
                Address1 = "1 Gwalior Road",
                Locality = "London",
                Country = "GB",
                PostalCode = "SW15 1NP"
            },
            Items = new[]
            {
                new ItemModel
                {
                    ItemId = "ABCD",
                    ItemType = ItemType.Product,
                    Price = 20,
                    Quantity = 1,
                    RestrictedCountries = new[] { "US" }
                }
            }
        };
    }

请注意,您的示例提供程序应该 return 您在 SwaggerResponse 属性中指定类型的实例(例如 DeliveryOptionsSearchModel)。

启用 Swagger 时不要忘记启用 ExamplesOperationFilter

services.AddSwaggerGen(c =>
{
     c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
     c.OperationFilter<ExamplesOperationFilter>();
}

更新

文档似乎有些过时了。 我必须执行以下操作才能启动示例提供程序:

services.AddSwaggerExamplesFromAssemblyOf<DeliveryOptionsSearchModelExample>();

.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo {Title = "Elsa", Version = "v1"});
    c.ExampleFilters();
})