<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.2" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="8.1.1" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
</ItemGroup>
public static class SwaggerServices
{
public static IServiceCollection AddSwaggerServices(
this IServiceCollection services
)
{
services.AddOpenApi();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc(
"v1",
new OpenApiInfo
{
Title = "Крестики-нолики",
Version = "v1",
Description = "API для пользователей",
Contact = new OpenApiContact
{
Url = new Uri("https://github.com/artemovsergey/TicTacToe"),
Email = "[email protected]",
}
}
);
c.EnableAnnotations();
c.SchemaFilter<ErrorResponseSchemaFilter>();
c.OperationFilter<ErrorResponseOperationFilter>();
});
return services;
}
}
public static class SwaggerMiddlewares
{
public static WebApplication UseSwaggerMiddleware(this WebApplication app)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Крестики-Нолики API");
c.RoutePrefix = string.Empty;
});
app.MapOpenApi();
return app;
}
}
// Фильтр для добавления примеров ErrorResponse
public class ErrorResponseSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (context.Type == typeof(ErrorResponse))
{
schema.Example = new OpenApiObject
{
["statusCode"] = new OpenApiString("400"),
["message"] = new OpenApiString("Invalid request"),
["detail"] = new OpenApiString("The 'id' parameter must be a positive number")
};
}
}
}
public class ErrorResponseOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var statusCodes = new Dictionary<string, (string Message, string Detail)>
{
["400"] = ("Invalid request", "The 'id' parameter must be a positive number"),
["404"] = ("Resource not found", "The requested resource was not found"),
["409"] = ("Conflict", "Поле занято"),
["412"] = ("Precondition failed", "Несогласованное состояние объекта Game"),
["500"] = ("Internal server error", "An unexpected error occurred")
};
foreach (var (code, (message, detail)) in statusCodes)
{
if (operation.Responses.TryGetValue(code, out var response) &&
response.Content.TryGetValue("application/json", out var mediaType))
{
mediaType.Example = new OpenApiObject
{
["statusCode"] = new OpenApiInteger(int.Parse(code)),
["message"] = new OpenApiString(message),
["detail"] = new OpenApiString(detail)
};
}
}
}
}