【问题标题】:Using Microsoft.AspNetCore.Mvc.Versioning, Swashbuckle.AspNetCore, and MaptoApiVersion使用 Microsoft.AspNetCore.Mvc.Versioning、Swashbuckle.AspNetCore 和 MaptoApiVersion
【发布时间】:2017-10-26 11:40:26
【问题描述】:

我在以下使用 MapToApiVersion 时遇到问题。从http://localhost:5000/swagger 开始,1.0 Docs 和 2.0 Docs 正确渲染了 swagger ui 并且对应的 swagger.json 文件可用。 3.0 Docs 渲染失败,swagger.json 文件似乎没有生成。

所有 3 个版本的实际服务都已启动并正常运行。如果我从邮递员那里得到它,我会得到我期望的响应。

这是运行 Mvc.Versioning 的 1.1.1-rc1 和 Swashbuckle.AspNetCore 的 1.0.0。下面是完整的 .csproj

完整代码https://github.com/senften/AspNetCoreVersionedWebApi/tree/maptoapiversion

当我在 Visual Studio Code 的调试中运行此程序时,我没有看到任何错误或任何异常。我是否搞砸了启动或声明,或者我只是在 shim 或 swashbuckle 中遇到了错误?

using Microsoft.AspNetCore.Mvc;
using VersionedWebApi.Model;

namespace VersionedWebApi.Controllers
{
    /// <summary>
    /// GoodByeController, just saying Goodbye!
    /// </summary>
    [ApiVersion("1.0", Deprecated = true)]
    [ApiVersion("3.0")]
    [Route("api/v{api-version:apiVersion}/[controller]")]
    public class GoodByeController : Controller
    {
        /// <summary>
        /// Default Get call returning Goodbye world!
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(GoodByeWorldModel), 200)]
        [ProducesResponseType(typeof(void), 404)]
        public GoodByeWorldModel Get()
        {
            return new GoodByeWorldModel();
        }

        /// <summary>
        /// Default Get call returning Goodbye world!
        /// </summary>
        /// <returns></returns>
        [HttpGet, MapToApiVersion("3.0")]
        [ProducesResponseType(typeof(VersionedWebApi.Model.v3.GoodByeWorldModel), 200)]
        [ProducesResponseType(typeof(void), 404)]
        public VersionedWebApi.Model.v3.GoodByeWorldModel GetV3()
        {
            return new VersionedWebApi.Model.v3.GoodByeWorldModel();
        }
    }
}

startup.cs

using System.Xml.XPath;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SwashbuckleAspNetVersioningShim;

namespace VersionedWebApi
{
    public class Startup
    {
        public Startup()
        {
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            var mvcBuilder = services.AddMvc();
            services.AddMvcCore().AddVersionedApiExplorer();

            // Adds versioning capabilities, defaulting to version 1.0 calls if available
            services.AddApiVersioning(o =>
            {
                o.AssumeDefaultVersionWhenUnspecified = true;
                o.DefaultApiVersion = new ApiVersion(1, 0);
            });

            // Add generated documentation
            services.AddSwaggerGen(c =>
            {
                var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
                SwaggerVersioner.ConfigureSwaggerVersions(c, provider);
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, ApplicationPartManager partManager, IApiVersionDescriptionProvider provider)
        {
            // Generate swagger.json
            app.UseSwagger();

            // Let's enable SwaggerUI
            app.UseSwaggerUI(c =>
            {
                SwaggerVersioner.ConfigureSwaggerVersions(c, provider);
            });

            app.UseMvc();
            // This is new for v1.1 and is a behavioral breaking change from previous (including 1.1-beta)
            // See the release notes: https://github.com/Microsoft/aspnet-api-versioning/releases/tag/v1.1-rc1
            app.UseApiVersioning();
        }
    }
}

csproj 文件

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
    <Company />
    <Description>A .NET Core Web API project demonstrating versioning a Web API and generating interactive documentation with Swagger.</Description>
    <RepositoryUrl>https://github.com/senften/AspNetCoreVersionedWebApi</RepositoryUrl>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DocumentationFile></DocumentationFile>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="1.1.0-rc1"/>
    <PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />
    <PackageReference Include="SwashbuckleAspNetVersioningShim" Version="1.0.0-beta4"/>
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0-msbuild3-final" />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="1.0.0"/>
    <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="*"/>
  </ItemGroup>

</Project>

【问题讨论】:

    标签: asp.net-core swagger swashbuckle


    【解决方案1】:

    您遇到的问题是 shim 库的行为。

    生成 Swagger 文档时,控制器上指定的 ApiVersions 将应用于其中未明确设置为其他内容的所有方法。 在这种情况下,因为 Get() 方法上没有 MapToApiVersion 属性,所以它被添加到 V1 和 V3 Swagger 文档中,因为这是控制器上指定的内容。这会在生成 Swagger 文档时导致过载错误。

    好消息是它是一个简单的修复,只需将 [HttpGet, MapToApiVersion("1.0")] 添加到您的 Get() 方法中,它看起来就像这样

    /// <summary>
    /// Default Get call returning Goodbye world!
    /// </summary>
    /// <returns></returns>
    [HttpGet, MapToApiVersion("1.0")]
    [ProducesResponseType(typeof(GoodByeWorldModel), 200)]
    [ProducesResponseType(typeof(void), 404)]
    public GoodByeWorldModel Get()
    {
        return new GoodByeWorldModel();
    }
    

    Get() 方法只会被添加到 V1 文档中,而您的其余代码可以保持原样。

    GitHub Readme 上为 Shim 提供了有关此行为的更多详细信息

    【讨论】:

      【解决方案2】:

      需要对您的代码进行几处更改。

      1) 将以下代码更改为

          [ApiVersion("3.0"), Route("api/v{api-version:apiVersion}/[controller]")]
          [Route("api/v{api-version:apiVersion}/[controller]")]
          public class HelloController : Controller
          { }
      
      
          [ApiVersion("3.0"), Route("api/v{api-version:apiVersion}/[controller]")]
          public class HelloController : Controller
          { }
      

      2) 添加 MapToApiVersion 1.0 避免冲突

      [HttpGet, MapToApiVersion("1.0")]
      [ProducesResponseType(typeof(GoodByeWorldModel), 200)]
      [ProducesResponseType(typeof(void), 404)]
      public GoodByeWorldModel Get()
      {
          return new GoodByeWorldModel();
      }
      

      【讨论】:

        猜你喜欢
        • 2020-05-04
        • 1970-01-01
        • 2019-11-15
        • 2017-04-17
        • 2020-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-10
        相关资源
        最近更新 更多