我刚刚更新了 api 版本控制库。
在我之前:
现在我有:
在此更新之前,版本是自动写入的,但现在需要我将其作为参数传递。
控制器:
[Route("v{version:apiVersion}/Sales")]
public class SalesController : CustomController
{
private readonly ISalesBusinessLogic _SalesBusinessLogic;
private readonly IValidator<getSalesRequestDto> _getSalesRequestDto;
public SalesController(
ISalesBusinessLogic SalesBusinessLogic,
IValidator<getSalesRequestDto> getSalesRequestDto
)
{
_SalesBusinessLogic = SalesBusinessLogic;
_getSalesRequestDto = getSalesRequestDto;
}
[MapToApiVersion("4.0")]
[HttpGet]
[SwaggerResponseExample(StatusCodes.Status200OK, typeof(SalesResponseViewModelExample))]
[SwaggerResponse(StatusCodes.Status200OK, Type = typeof(GlobalResponse<SalesResponseViewModel>))]
public async Task<IActionResult> getSales([FromQuery] getSalesRequestDto request)
{
var results = await _getSalesRequestDto.ValidateAsync(request);
results.AddToModelState(ModelState, null);
if (!results.IsValid)
{
return new ValidationFailedResult(results);
}
var result = await _SalesBusinessLogic.getSales(request);
return Ok(result);
}
}
自定义控制器:
[ApiController]
[EnableCors("cors")]
[Authorize]
[ApiVersion("4.0")]
[Produces(MediaTypeNames.Application.Json)]
[SwaggerResponseExample(StatusCodes.Status500InternalServerError, typeof(GlobalResponseErrorExample))]
[SwaggerResponse(StatusCodes.Status500InternalServerError, Type = typeof(GlobalResponse<object>))]
[SwaggerResponseExample(StatusCodes.Status401Unauthorized, typeof(GlobalResponseInvalidTokenExample))]
[SwaggerResponse(StatusCodes.Status401Unauthorized, Type = typeof(GlobalResponse<object>))]
public class CustomController : ControllerBase
{
}
配置SwaggerOptions:
public class ConfigureSwaggerOptions : IConfigureNamedOptions<SwaggerGenOptions>
{
private readonly IApiVersionDescriptionProvider provider;
public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider)
{
this.provider = provider;
}
public void Configure(SwaggerGenOptions options)
{
// add swagger document for every API version discovered
foreach (var description in provider.ApiVersionDescriptions)
{
options.SwaggerDoc(
description.GroupName,
CreateVersionInfo(description));
options.ExampleFilters();
options.AddSecurityDefinition(
description.GroupName,
CreateSecurityScheme());
options.AddSecurityRequirement(CreateSecurityRequirement(description.GroupName));
}
}
public void Configure(string name, SwaggerGenOptions options)
{
Configure(options);
}
private OpenApiInfo CreateVersionInfo(ApiVersionDescription description)
{
var info = new OpenApiInfo()
{
Title = "API eCommerce",
Version = description.ApiVersion.ToString()
};
if (description.IsDeprecated)
{
info.Description += " This API version has been deprecated.";
}
return info;
}
private OpenApiSecurityScheme CreateSecurityScheme()
{
var securityScheme = new OpenApiSecurityScheme()
{
Name = "Authorization",
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Description = "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer token\"",
};
return securityScheme;
}
private OpenApiSecurityRequirement CreateSecurityRequirement(string groupName)
{
var securityRequirement = new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme{
Reference = new OpenApiReference
{Type = ReferenceType.SecurityScheme, Id = groupName}
}, new string[] {}
}
};
return securityRequirement;
}
}
程序.cs:
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.ConfigureOptions<ConfigureSwaggerOptions>();
//API Versioning
builder.Services.AddApiVersioning(options =>
{
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(4, 0);
options.ReportApiVersions = true;
}).AddApiExplorer(setup =>
{
setup.GroupNameFormat = "'v'VVV";
setup.SubstituteApiVersionInUrl = true;
}).AddMvc();
var app = builder.Build();
var provider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(options =>
{
foreach (var description in provider.ApiVersionDescriptions)
{
options.SwaggerEndpoint($"{description.GroupName}/swagger.json",
description.GroupName.ToUpperInvariant());
}
});
}
我缺少什么配置?
我设法使用这一行找到解决方案:
options.Conventions.Add(new VersionByNamespaceConvention())
在program.cs中看起来像这样:
builder.Services.AddApiVersioning(options =>
{
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(4, 0);
options.ReportApiVersions = true;
}).AddApiExplorer(setup =>
{
setup.GroupNameFormat = "'v'VVV";
setup.SubstituteApiVersionInUrl = true;
}).AddMvc(
options =>
{
// automatically applies an api version based on the name of
// the defining controller's namespace
options.Conventions.Add(new VersionByNamespaceConvention());
});