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

HTT*_*HTT 8 c# swagger-ui json-api swashbuckle asp.net-core

我使用来自jsonapi.orgJSONAPI规范,然后我使用JsonApiSerializer来完成 JSONAPI 规范,所以我的响应和请求正文如下所示:

{    
    "data": {
    "type": "articles",
    "id": "stringId",
    "attributes": {
      "title": "JSON:API paints my bikeshed!"
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个实体“文章”,它看起来像:

public class Article
{
     public string Id { get; set; }
     public string title { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

{
     "id": "string",
     "title": "string"
}
Run Code Online (Sandbox Code Playgroud)

我认为 swagger 忽略了JsonApiSerializer,有没有办法更改 swagger 的默认序列化程序并使用我自己的序列化程序?

我的 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();
            });
        }
    }
Run Code Online (Sandbox Code Playgroud)
  • 网核 3.1
  • Swashbuckle.AspNetCore 5.0.0

Sip*_*tra 4

您可以使用以下命令生成示例 swagger 请求和响应Swashbuckle.AspNetCore.Filters生成示例 swagger 请求和响应。

\n

从引用的博客文章之一复制的示例:

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

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

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

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

\n

不要忘记启用ExamplesOperationFilter不要\xe2\x80\x99在启用 Swagger 时

\n
services.AddSwaggerGen(c =>\n{\n     c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });\n     c.OperationFilter<ExamplesOperationFilter>();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

更新

\n

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

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