如何将自定义模型绑定器与 Swashbuckle、Swagger 和 NSwag 一起使用?
How to use a custom model binder with Swashbuckle, Swagger and NSwag?
我有一个 ASP.NET 核心 Web API,其中包含以下端点。
[HttpGet]
[Route("models/{ids}")]
[Produces(typeof(IEnumerable<Model>))]
public IActionResult Get
(
[ModelBinder(typeof(CsvModelBinder<string>))] IEnumerable<string> ids
)
{
// Get models
return Ok(models);
}
此端点采用 Ids 的 CSV 列表(例如 /models/a,b,c
)和 returns 相应 Model
对象的 JSON 数组。 CsvModelBinder<string>
是我编写的 IModelBinder
的自定义实现,它将 ID 的 CSV 列表拆分为 IEnumerable<string>
,我可以在查询中使用它来查找对象。这一切都很好。
我现在尝试做的是使用 NSwag 生成客户端库,但这被证明是有问题的,因为 Swashbuckle 生成的 Swagger 将 ids
参数描述为 IEnumerable<string>
,而不是string
.
选项 A: 有没有办法告诉 Swashbuckle 将参数描述为 string
而不是 IEnumerable<string>
?
选项 B: 有没有办法告诉 NSwag 在生成请求 URL 时应该将此 IEnumerable<string>
参数编组到 CSV 中?
您可以编写自定义操作过滤器 (Swashbuckle) 或操作处理器 (NSwag) 以将规范中的给定参数转换为纯字符串。
我明白了。我需要在 Startup.cs
中使用 MapType() 创建自定义模型
Csv.cs
public class Csv<T> : List<T> where T : IConvertible
{
public Csv<T> Append(string delimitedValues)
{
var splitValues = delimitedValues
.Split(',', StringSplitOptions.RemoveEmptyEntries)
.Cast<string>();
var convertedValues = splitValues
.Select(str => Convert.ChangeType(str, typeof(T)))
.Cast<T>();
this.AddRange(convertedValues);
return this;
}
public override string ToString()
{
return this.Aggregate("", (a,s) => $"{a},{s}").Trim(',');
}
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSwaggerGen(c =>
{
c.IncludeXmlComments(() => new XPathDocument(new FileStream(Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "MyApi.xml"), FileMode.Open)));
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1"});
c.MapType<Csv<string>>(() => new Schema { Type = "string", Format = "string" });
});
}
我有一个 ASP.NET 核心 Web API,其中包含以下端点。
[HttpGet]
[Route("models/{ids}")]
[Produces(typeof(IEnumerable<Model>))]
public IActionResult Get
(
[ModelBinder(typeof(CsvModelBinder<string>))] IEnumerable<string> ids
)
{
// Get models
return Ok(models);
}
此端点采用 Ids 的 CSV 列表(例如 /models/a,b,c
)和 returns 相应 Model
对象的 JSON 数组。 CsvModelBinder<string>
是我编写的 IModelBinder
的自定义实现,它将 ID 的 CSV 列表拆分为 IEnumerable<string>
,我可以在查询中使用它来查找对象。这一切都很好。
我现在尝试做的是使用 NSwag 生成客户端库,但这被证明是有问题的,因为 Swashbuckle 生成的 Swagger 将 ids
参数描述为 IEnumerable<string>
,而不是string
.
选项 A: 有没有办法告诉 Swashbuckle 将参数描述为 string
而不是 IEnumerable<string>
?
选项 B: 有没有办法告诉 NSwag 在生成请求 URL 时应该将此 IEnumerable<string>
参数编组到 CSV 中?
您可以编写自定义操作过滤器 (Swashbuckle) 或操作处理器 (NSwag) 以将规范中的给定参数转换为纯字符串。
我明白了。我需要在 Startup.cs
中使用 MapType() 创建自定义模型Csv.cs
public class Csv<T> : List<T> where T : IConvertible
{
public Csv<T> Append(string delimitedValues)
{
var splitValues = delimitedValues
.Split(',', StringSplitOptions.RemoveEmptyEntries)
.Cast<string>();
var convertedValues = splitValues
.Select(str => Convert.ChangeType(str, typeof(T)))
.Cast<T>();
this.AddRange(convertedValues);
return this;
}
public override string ToString()
{
return this.Aggregate("", (a,s) => $"{a},{s}").Trim(',');
}
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSwaggerGen(c =>
{
c.IncludeXmlComments(() => new XPathDocument(new FileStream(Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "MyApi.xml"), FileMode.Open)));
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1"});
c.MapType<Csv<string>>(() => new Schema { Type = "string", Format = "string" });
});
}