如何设置Swashbuckle与Microsoft.AspNetCore.Mvc.Versioning [英] How to set up Swashbuckle vs Microsoft.AspNetCore.Mvc.Versioning

查看:44
本文介绍了如何设置Swashbuckle与Microsoft.AspNetCore.Mvc.Versioning的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有asp.net核心webapi.我们添加了Microsoft.AspNetCore.Mvc.VersioningSwashbuckle来拥有醒目的UI. 我们将控制器指定为:

We have asp.net core webapi. We added Microsoft.AspNetCore.Mvc.Versioning and Swashbuckle to have swagger UI. We specified controllers as this:

[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public class ContactController : Controller
{

当我们运行swagger ui时,我们在路由中获取version作为参数:

When we run swagger ui we get version as parameter in routes:

如何为路由设置默认的"v1"? 如果版本2登台,如何为两个版本都支持swagger ui?

How to set-up default "v1" for route ? If version 2 come to the stage how support swagger ui for both versions ?

推荐答案

目前,Swashbuckle和Microsoft.AspNetCore.Mvc.Versioning是朋友.效果很好.我刚刚在VS2017中创建了测试项目,并检查了它的工作方式.

At the moment Swashbuckle and Microsoft.AspNetCore.Mvc.Versioning are friends. It works good. I just created test project in VS2017 and checked how it works.

首先包括以下两个nuget程序包:

First include these two nuget packages:

<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="1.2.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />

配置Startup.cs中的所有内容(阅读我的评论):

Configure everything in Startup.cs (read my comments):

public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();


        // Configure versions 
        services.AddApiVersioning(o =>
        {
            o.AssumeDefaultVersionWhenUnspecified = true;
            o.DefaultApiVersion = new ApiVersion(1, 0);
        });

        // Configure swagger
        services.AddSwaggerGen(options =>
        {
            // Specify two versions 
            options.SwaggerDoc("v1", 
                new Info()
                {
                    Version = "v1",
                    Title = "v1 API",
                    Description = "v1 API Description",
                    TermsOfService = "Terms of usage v1"
                });

            options.SwaggerDoc("v2",
                new Info()
                {
                    Version = "v2",
                    Title = "v2 API",
                    Description = "v2 API Description",
                    TermsOfService = "Terms of usage v2"
                });

            // This call remove version from parameter, without it we will have version as parameter 
            // for all endpoints in swagger UI
            options.OperationFilter<RemoveVersionFromParameter>();

            // This make replacement of v{version:apiVersion} to real version of corresponding swagger doc.
            options.DocumentFilter<ReplaceVersionWithExactValueInPath>();

            // This on used to exclude endpoint mapped to not specified in swagger version.
            // In this particular example we exclude 'GET /api/v2/Values/otherget/three' endpoint,
            // because it was mapped to v3 with attribute: MapToApiVersion("3")
            options.DocInclusionPredicate((version, desc) =>
            {
                var versions = desc.ControllerAttributes()
                    .OfType<ApiVersionAttribute>()
                    .SelectMany(attr => attr.Versions);

                var maps = desc.ActionAttributes()
                    .OfType<MapToApiVersionAttribute>()
                    .SelectMany(attr => attr.Versions)
                    .ToArray();

                return versions.Any(v => $"v{v.ToString()}" == version) && (maps.Length == 0 || maps.Any(v => $"v{v.ToString()}" == version));
            });

        });

    }

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint($"/swagger/v2/swagger.json", $"v2");
            c.SwaggerEndpoint($"/swagger/v1/swagger.json", $"v1");
        });
        app.UseMvc();
    }

有两个类可以解决问题:

There two classes that make the trick:

public class RemoveVersionFromParameter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        var versionParameter = operation.Parameters.Single(p => p.Name == "version");
        operation.Parameters.Remove(versionParameter);
    }
}

public class ReplaceVersionWithExactValueInPath : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
    {
        swaggerDoc.Paths = swaggerDoc.Paths
            .ToDictionary(
                path => path.Key.Replace("v{version}", swaggerDoc.Info.Version),
                path => path.Value
            );
    }
}

RemoveVersionFromParameter从swagger用户界面中删除以下文本框:

The RemoveVersionFromParameter removes from swagger UI this textbox:

ReplaceVersionWithExactValueInPath对此进行更改:

对此:

Controller类现在看起来如下:

Controller class looks now as follows:

[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1")]
[ApiVersion("2")]
public class ValuesController : Controller
{
    // GET api/values
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/values/5
    [HttpGet("{id}")]
    public string Get(int id)
    {
        return "value";
    }

    // POST api/values
    [HttpPost]
    public void Post([FromBody]string value)
    {
    }

    // PUT api/values/5
    [HttpPut("{id}")]
    public void Put(int id, [FromBody]string value)
    {
    }

    // DELETE api/values/5
    [HttpDelete("{id}")]
    public void Delete(int id)
    {
    }


    [HttpGet("otherget/one")]
    [MapToApiVersion("2")]
    public IEnumerable<string> Get2()
    {
        return new string[] { "value1", "value2" };
    }

    /// <summary>
    /// THIS ONE WILL BE EXCLUDED FROM SWAGGER Ui, BECAUSE v3 IS NOT SPECIFIED. 'DocInclusionPredicate' MAKES THE
    /// TRICK 
    /// </summary>
    /// <returns></returns>
    [HttpGet("otherget/three")]
    [MapToApiVersion("3")]
    public IEnumerable<string> Get3()
    {
        return new string[] { "value1", "value2" };
    }
}


代码: https://gist.github.com/Alezis/bab8b559d0d8800c994d065db03ab53e

这篇关于如何设置Swashbuckle与Microsoft.AspNetCore.Mvc.Versioning的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆