C# Api Controller - How to implement swagger oneOf

57 Views Asked by At

I have to implement this kind of Api Controller in C#:

       requestBody:
        description: A JSON object containing pet information
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/Cat'
                - $ref: '#/components/schemas/Dog'
                - $ref: '#/components/schemas/Hamster'

oneOf docs: https://swagger.io/docs/specification/describing-request-body/ Expected output:

enter image description here

I'm using: <PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.5.0" />

I have already tried with dynamic or Interface but the swagger generator didn't do oneOf schema as in the image.

Do you have a C# example?

1

There are 1 best solutions below

3
Jason Pan On BEST ANSWER

Here is the tutorial for you, hope it can help you.

1. Create a Basic WebApi Project like below.

enter image description here

2. Using below settings in Program.cs

    builder.Services.AddSwaggerGen(swaggerGenOptions =>
    {
        swaggerGenOptions.UseAllOfForInheritance();
        swaggerGenOptions.UseOneOfForPolymorphism();

        swaggerGenOptions.SelectSubTypesUsing(baseType =>
            typeof(Program).Assembly.GetTypes().Where(type => type.IsSubclassOf(baseType))
        );
    });

enter image description here

3. Modify the WeatherForecast.cs file.

namespace SwaggerOneOf
{
    public class WeatherForecast
    {
        public DateTime Date { get; set; }

        public int TemperatureC { get; set; }

        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

        public string? Summary { get; set; }
    }

    public class WeatherForecastWithLocation : WeatherForecast
    {
        public string? Location { get; set; }
    }
}

4. Modify the method on controller.

using Microsoft.AspNetCore.Mvc;

namespace SwaggerOneOf.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }
        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get() =>
            DateTime.Now.Minute < 30
                ? Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = Random.Shared.Next(-20, 55),
                    Summary = Summaries[Random.Shared.Next(Summaries.Length)]
                })
                : Enumerable.Range(1, 5).Select(index => new WeatherForecastWithLocation
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = Random.Shared.Next(-20, 55),
                    Summary = Summaries[Random.Shared.Next(Summaries.Length)],
                    Location = "London"
                })
                .ToArray();
    }
}

5. Test Result

enter image description here

enter image description here