首页 > 解决方案 > 如何在asp.net core 2.2 web api中使用不同版本的相同参数创建相同的路由名称

问题描述

我想用不同版本调用具有相同路由名称(相同参数)的服务...

下面是我的代码

[Route("api/v{version:apiVersion}/[controller]/")]
    [ApiController]
    [ApiVersion("1.0")]
    [ApiVersion("1.1")]
    public class AccountController : ControllerBase
    {
    [MapToApiVersion("1")]
    [HttpGet("getacounttypes")]
    [ProducesResponseType(typeof(Models.ReturnString), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(Models.ErrorMessage), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(Models.ErrorMessage), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult> GetAddressTypes()
    {
        logger.LogInformation("Request is processing at account types");
        try
        {
            return Ok(await accountBS.GetAccountTypes());
        }
        catch (ArgumentException ex)
        {
            logger.LogError(ex, ex.Message);
            this.Response.StatusCode = StatusCodes.Status400BadRequest;
            return new JsonResult(new Models.ErrorMessage() { Code = StatusCodes.Status400BadRequest.ToString(), Message = ex.Message });
        }
        catch (Exception e)
        {
            logger.LogError(e, e.Message);
            this.Response.StatusCode = StatusCodes.Status500InternalServerError;
            return new JsonResult(new Models.ErrorMessage() { Code = StatusCodes.Status500InternalServerError.ToString(), Message = e.Message });
        }
    }


    [MapToApiVersion("1.1")]
    [HttpGet("getacounttypes")]
    [ProducesResponseType(typeof(Models.ReturnString), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(Models.ErrorMessage), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(Models.ErrorMessage), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult> GetAddressTypesV1_1()
    {
        logger.LogInformation("Request is processing at account types");
        try
        {
            return Ok(await accountBS.GetAccountTypes());
        }
        catch (ArgumentException ex)
        {
            logger.LogError(ex, ex.Message);
            this.Response.StatusCode = StatusCodes.Status400BadRequest;
            return new JsonResult(new Models.ErrorMessage() { Code = StatusCodes.Status400BadRequest.ToString(), Message = ex.Message });
        }
        catch (Exception e)
        {
            logger.LogError(e, e.Message);
            this.Response.StatusCode = StatusCodes.Status500InternalServerError;
            return new JsonResult(new Models.ErrorMessage() { Code = StatusCodes.Status500InternalServerError.ToString(), Message = e.Message });
        }
    }
}

在这个我有错误

An unhandled exception has occurred while executing the request.
System.NotSupportedException: HTTP method "GET" & path "api/v{version}/Account/[actions]/getacounttypes" overloaded by actions - API.Controllers.AccountController.GetAddressTypes (GSOnline.API),
API.Controllers.AccountController.GetAddressTypesV1_1 . Actions require unique method/path combination for Swagger 2.0. Use ConflictingActionsResolver as a workaround
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreatePathItem(IEnumerable`1 apiDescriptions, ISchemaRegistry schemaRegistry)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreatePathItems(IEnumerable`1 apiDescriptions, ISchemaRegistry schemaRegistry)
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwagger(String documentName, String host, String basePath, String[] schemes)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

所以你能建议我使用相同参数和不同版本的相同路由的解决方案吗?我可以管理具有差异参数的方法,但我正在寻找具有相同参数的相同路由......

预期结果是

GET
/api/v1/Account/getacounttypes
GET
/api/v1.1/Account/getacounttypes

标签: swaggerasp.net-core-webapiasp.net-core-2.0api-versioning

解决方案


您的问题并不完全清楚,但您似乎指的是使用 Swashbuckle 生成单个 OpenAPI/Swagger 文档。通常,Swashbuckle 将为每个 API 版本创建一个文档。使用 URL 分段方法,可以创建包含所有 URL 的单个文档。该文档仅允许从路由模板派生的不同 URL。路由参数在请求时填写,但文档生成器不知道或不理解这一点。

要实现此行为,您需要让 API Explorer 在生成描述时填写 API 版本。您的配置应如下所示:

services.AddVersionedApiExplorer(options => options.SubstituteApiVersionInUrl = true);

配置此选项后,API 版本将代表您自动替换并达到您的预期结果。


推荐阅读