基于NSwag.CodeGeneration.CSharp生成Swagger/OpenAPI客户端C#代码

Posted ldybyz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于NSwag.CodeGeneration.CSharp生成Swagger/OpenAPI客户端C#代码相关的知识,希望对你有一定的参考价值。

Swagger (OpenAPI) 是一个与语言无关的规范,用于描述 REST API。 它使计算机和用户无需直接访问源代码即可了解 REST API 的功能。即你无论是用C#,java还是python构建REST API,你的文档规范都是一样的。

 

我们可以根据文档生成我们的api客户端代码,当然自己搞也可以,但是花费时间比较多。网上找了下,有以下几种方式:

1.NSwagStudio

2.NSwag.CodeGeneration.CSharp 或 NSwag.CodeGeneration.TypeScript NuGet 包 - 用于在项目中生成代码。

3.通过命令行使用 NSwag。

4.NSwag.MSBuild NuGet 包。

5.Unchase OpenAPI (Swagger) Connected Service(Unchase OpenAPI (Swagger) 连接服务):一种 Visual Studio 连接服务,用于在 C# 或 TypeScript 中生成 API 客户端代码。 还可以使用 NSwag 为 OpenAPI 服务生成 C# 控制器。

6.AutoRest

7.swagger-codegen

 

对比了这几种方式,发现很多都是生成单个cs文件,有部分有模板(swagger-codegen是用java实现的,还没研究),最终觉得NSwagStudio和NSwag.CodeGeneration.CSharp比较好用。

所以简单的研究了一下使用方式,NSwagStudio目前只能生成单个文件,可以自定义模板,算是比较好用。

若引用NSwag.CodeGeneration.CSharp包自己进行编程,可实现生成多个文件。鉴于网上资料比较少,文档也不详细,这里简单写一下代码和使用方式

 

1.默认实现方式,单个cs文件生成

System.Net.WebClient wclient = new System.Net.WebClient();         

var document = await OpenApiDocument.FromJsonAsync(wclient.DownloadString("Https://SwaggerSpecificationURL.json"));

wclient.Dispose();

var settings = new CSharpClientGeneratorSettings
{
    ClassName = "MyClass", 
    CSharpGeneratorSettings = 
    {
        Namespace = "MyNamespace"
    }
};

var generator = new CSharpClientGenerator(document, settings);	
var code = generator.GenerateFile();

  

2.多个cs文件生成,根据多个控制器生成多个cs客户端代码,多个请求和返回值类型也实现多个文件的输出

-首先定义一个继承类把方法开放出来

 public class MultiCSharpClientGenerator : CSharpClientGenerator
    {
        public MultiCSharpClientGenerator(OpenApiDocument document, CSharpClientGeneratorSettings settings) : base(document, settings)
        {
        }

        public MultiCSharpClientGenerator(OpenApiDocument document, CSharpClientGeneratorSettings settings, CSharpTypeResolver resolver) : base(document, settings, resolver)
        {
        }

        /// <summary>
        /// 获取请求和返回值实体类型代码集合
        /// </summary>
        /// <returns></returns>
        public new IEnumerable<CodeArtifact> GenerateDtoTypes()
        {
            return base.GenerateDtoTypes();
        }

        /// <summary>
        /// 获取客户端代码集合
        /// </summary>
        /// <returns></returns>
        public new IEnumerable<CodeArtifact> GenerateAllClientTypes()
        {
            return base.GenerateAllClientTypes();
        }

    }

 

-批量生成代码文件

class Program
    {
        static async void Main(string[] args)
        {
            System.Net.WebClient wclient = new System.Net.WebClient();
            var document =await OpenApiDocument.FromJsonAsync(wclient.DownloadString("Https://SwaggerSpecificationURL.json"));
            wclient.Dispose();

            var settings = new CSharpClientGeneratorSettings
            {
                CSharpGeneratorSettings =
                {
                Namespace = "MyNamespace"
                },
               
                //设置模板路径
                CodeGeneratorSettings=
                {
                    TemplateDirectory="E:\\\\nswag\\\\CustomTemplates",
                    
                },
                //设置多个控制器客户端代码生成
                OperationNameGenerator=new MultipleClientsFromFirstTagAndOperationIdGenerator()


            };

            var generator2 = new MultiCSharpClientGenerator(document, settings);

            //生成实体类文件
            foreach (var t in generator2.GenerateDtoTypes())
            {
                WriteMyTypeToFile(t.TypeName, t.Code);
            }
    
            //生成客户端类文件
            foreach (var t in generator2.GenerateAllClientTypes())
            {
                WriteMyTypeToFile(t.TypeName, t.Code);
            }

            Console.WriteLine("代码生成完成");
            Console.ReadLine();

        }

        /// <summary>
        /// 创建文件
        /// </summary>
        /// <param name="name"></param>
        /// <param name="code"></param>
        private static void WriteMyTypeToFile(string name,string code)
        {
            string path = @"D:\\TestNSwag";
            if (!Directory.Exists(path))
            {
                DirectoryInfo di = Directory.CreateDirectory(path);

            }
            var filepath = Path.Combine(path, $"{name}.cs");

            using (StreamWriter writer = File.CreateText(filepath))
            {
                
                 writer.Write(code);
               
            }
        }
    }

 

代码有点简陋,后期需要优化,其中TypeName是类型名称,Code是代码,生成文件的时候可以根据自己的需要做修改。

模板可以从NSwag上获取,可以自己修改,使用的是liquid类型的文件

有一个问题还无法解决,就是泛型类型生成的文件有点问题,貌似还没得到解决,这里贴一下讨论的链接

如有其他实现方式和建议请留言

 

 

参考资料:NSwagaspnetcore官方文档OpenAPI规范 ......

 

以上是关于基于NSwag.CodeGeneration.CSharp生成Swagger/OpenAPI客户端C#代码的主要内容,如果未能解决你的问题,请参考以下文章

基于内容与基于协作的过滤?

为啥 Kafka 是基于拉的而不是基于推的?

推荐算法简介:基于用户的协同过滤基于物品的协同过滤基于内容的推荐

依存句法分析:基于图的依存句法分析基于转移的依存句法分析基于神经网络的依存句法分析

基于项目和基于内容的协同过滤有啥区别?

事件处理:基于功能的组件与基于类的组件