【问题标题】:How to make same routing name with same parameter with different versions in asp.net core 2.2 web api如何在asp.net core 2.2 web api中使用不同版本的相同参数创建相同的路由名称
【发布时间】:2020-10-06 01:30:14
【问题描述】:

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

下面是我的代码

[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

【问题讨论】:

    标签: swagger asp.net-core-webapi asp.net-core-2.0 api-versioning


    【解决方案1】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2018-05-28
      • 1970-01-01
      • 2020-02-18
      • 1970-01-01
      • 2018-07-09
      • 1970-01-01
      • 2017-05-27
      • 2018-11-04
      • 2021-05-29
      相关资源
      最近更新 更多