为了简化问题,我在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
我如何使它使用泛型类,而不是为每个响应创建一个新类。在一个更大的项目中,会有太多的课程无缘无故。
1条答案
按热度按时间huwehgph1#
你看到的行为是按照设计的。当Swagger生成OpenAPI规范(它支撑着您正在查看的Swagger UI)时,它需要为API中的每个不同模型创建唯一的模式定义。在这种情况下,MySmartList、MySmartList和MySmartList都被视为不同的模型,而不仅仅是泛型类的示例。
自动生成的名称(如Int32MySmartList、StringMySmartList、WeatherForecastMySmartList)是由Swagger UI工具通过将类型参数附加到MySmartList等泛型类的类名来生成的。
为了尽量减少在Swagger文档中创建大量类,您可以考虑在API响应中限制泛型的使用。但是,这种方法需要为每个端点创建不同的响应类,这可能导致重复的代码。
如果这种折衷是可以接受的,那么您可以创建特定的类,如WeatherForecastList、NumberList、StringList等,其中每个类都将拥有与MySmartList相同的属性,但使用固体类型而不是泛型类型。例如:
这样,您就可以自己定义每个类,从而可以更好地控制Swagger文档中的类名。这可能会导致代码重复,但有助于在Swagger文档中保持一致的命名模式。