我有一个带有一些预定义路由模板的基本控制器:
[Authorize]
[ApiController]
[Produces(MediaTypeNames.Application.Json)]
public abstract class TenantControllerBase : ControllerBase
{
public const string DefaultRoute = "api/s/{serviceId:int}/[controller]";
private readonly ITenantContext _tenantContext; // Extracts the value of serviceId in a middelware
protected int ServiceId => _tenantContext.ServiceId;
protected TenantControllerBase(ITenantContext tenantContext)
{
_tenantContext = tenantContext ?? throw new ArgumentNullException(nameof(tenantContext));
}
}
这个想法是能够使用中间件检索serviceId
,并使其可用于从TenantControllerBase
继承的所有控制器,而无需每次在操作中显式地将其作为输入参数:
[Route(DefaultRoute)]
public class SomeTenantController : TenantControllerBase
{
public SomeTenantController(ITenantContext tenantContext) : base(tenantContext) { }
[HttpGet("{type}")]
public async Task<IActionResult> Get(string type, CancellationToken cancellationToken)
{
var serviceId = this.ServiceId;
// ...
return Ok();
}
}
这样做的问题是Swagger规范将serviceId
的类型设置为字符串,而不是路由模板中指定的整数:
"/api/s/{serviceId}/SomeTenant/{type}": {
"get": {
"tags": [
"SomeTenant"
],
"parameters": [
{
"name": "type",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string"
}
},
{
"name": "serviceId",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
就我所尝试的而言,让Swagger理解serviceId
是一个整数的唯一方法是显式地将其添加到action方法签名中:
[HttpGet("{type}")]
public async Task<IActionResult> Get(
string type,
int serviceId,
CancellationToken cancellationToken)
{
// serviceId is the same as the base field this.ServiceId;
// ...
return Ok();
}
有没有办法强制swagger根据路由模板api/s/{serviceId:int}/[controller]
中指定的值类型来设置值类型,而不必显式地将其添加到action方法签名中?
1条答案
按热度按时间b91juud31#
您可以使用一个简单的操作过滤器来修补它,以更新所有端点的服务ID参数类型:
启动注册:
不再对字符串值有效: