webapi泛型类响应swagger文档问题

fnatzsnv  于 2023-06-22  发布在  其他
关注(0)|答案(1)|浏览(163)

为了简化问题,我在GitHub上创建了一个repo供您参考。完整的代码可以通过https://github.com/ullfindsmit/SwaggerGenIssue访问,下面提到的类可以通过https://github.com/ullfindsmit/SwaggerGenIssue/blob/main/Controllers/WeatherForecastController.cs访问。
我创建了一个泛型类MySmartList

public class MySmartList<GenericType>
{
    public int TotalRows { get; set; }
    public List<GenericType> data { get; set; } = new List<GenericType>();
    public int PageNum { get; set; }
    public int PageSize { get; set; }
}

然后我使用相同的MySmartList类返回不同类的多个响应。

[Route("GetWeatherForecast")]
[HttpGet]
public MySmartList<WeatherForecast> GetWeatherForecast()
{
    MySmartList<WeatherForecast> result = new MySmartList<WeatherForecast>(); 

    result.data = Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
        TemperatureC = Random.Shared.Next(-20, 55),
        Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    }).ToList();

    return result;
}

[Route("GetNumbers")]
[HttpGet]
public MySmartList<int> GetNumbers()
{
    MySmartList<int> result = new MySmartList<int>();
    for (int i = 0; i < 10; i++)
    {
        result.data.Add(i);
    }
    return result;
}

[Route("GetStrings")]
[HttpGet]
public MySmartList<string> GetStrings()
{
    MySmartList<string> result = new MySmartList<string>();
    for (int i = 0; i < 10; i++)
    {
        result.data.Add(new Guid().ToString());
    }
    return result;
}

现在,当swagger生成文档时,它会为每个响应创建一个新类。Int32MySmartList StringMySmartList WeatherForecastMySmartList

我如何使它使用泛型类,而不是为每个响应创建一个新类。在一个更大的项目中,会有太多的课程无缘无故。

huwehgph

huwehgph1#

你看到的行为是按照设计的。当Swagger生成OpenAPI规范(它支撑着您正在查看的Swagger UI)时,它需要为API中的每个不同模型创建唯一的模式定义。在这种情况下,MySmartList、MySmartList和MySmartList都被视为不同的模型,而不仅仅是泛型类的示例。
自动生成的名称(如Int32MySmartList、StringMySmartList、WeatherForecastMySmartList)是由Swagger UI工具通过将类型参数附加到MySmartList等泛型类的类名来生成的。
为了尽量减少在Swagger文档中创建大量类,您可以考虑在API响应中限制泛型的使用。但是,这种方法需要为每个端点创建不同的响应类,这可能导致重复的代码。
如果这种折衷是可以接受的,那么您可以创建特定的类,如WeatherForecastList、NumberList、StringList等,其中每个类都将拥有与MySmartList相同的属性,但使用固体类型而不是泛型类型。例如:

public class WeatherForecastList
{
    public int TotalRows { get; set; }
    public List<WeatherForecast> data { get; set; } = new List<WeatherForecast>();
    public int PageNum { get; set; }
    public int PageSize { get; set; }
}

[Route("GetWeatherForecast")]
[HttpGet]
public WeatherForecastList GetWeatherForecast()
{
    WeatherForecastList result = new WeatherForecastList(); 

    result.data = Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
        TemperatureC = Random.Shared.Next(-20, 55),
        Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    }).ToList();

    return result;
}

这样,您就可以自己定义每个类,从而可以更好地控制Swagger文档中的类名。这可能会导致代码重复,但有助于在Swagger文档中保持一致的命名模式。

相关问题