【问题标题】:NSwag autogenerated client does not show default valuesNSwag 自动生成的客户端不显示默认值
【发布时间】:2022-07-11 16:38:41
【问题描述】:

我有一个启用了 Swagger 的 api。在其中一个端点中,我有一个请求,其中一些值设置为默认值。

[DefaultValue("test value")]
public string? Description { get; set; }

这在 api 的 Swagger 页面中看起来不错。 Swagger 示例中使用默认值。

我们使用 NSwag 生成一个在网关中使用的 api 客户端。当我生成这样一个客户端时,请求对象如下所示:

[System.Text.Json.Serialization.JsonPropertyName("description")]
public string? Description { get; set; } = "test value";

赋值对网关中的Swagger定义没有影响,因此该值显示为描述:“字符串”

如何正确地将 DefaultValue 注释传输到自动生成的客户端,以便我可以重用请求对象并显示带有测试值字符串集的示例?

api 的 swagger.json 对于描述字段如下所示:

"properties": {
          "description": {
            "type": "string",
            "default": "test value",
            "nullable": true
          },

Code based on the solution described below:
public static string AddAttributesToParametersForNSwag(string source, OpenApiDocument doc)
        {
            Dictionary<SyntaxNode, SyntaxNode> dict = new Dictionary<SyntaxNode, SyntaxNode>();
            SyntaxTree tree = CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(LanguageVersion.LatestMajor, DocumentationMode.Parse, SourceCodeKind.Regular));

            var root = (CompilationUnitSyntax)tree.GetRoot();

            var classes = tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>();

            if (classes.Count() == 0)
            {
                return root.ToFullString();
            }

            foreach (var classDeclaration in classes.Skip(1))
            {
                var className = classDeclaration.Identifier.ValueText;
                var classParameters = classDeclaration.DescendantNodes().OfType<PropertyDeclarationSyntax>();

                foreach (var classParameter in classParameters)
                {
                    string classParameterName = classParameter.Identifier.ValueText;

                    //Try to find classname as schema in the swagger document
                    var scheme = doc.Components.Schemas.Where(s => s.Key.ToLower() == className.ToLower()).FirstOrDefault();

                    if (scheme.Key == null || scheme.Value == null)
                    {
                        continue;
                    }

                    //Check if schema has the property we're looking for
                    var swaggerProperty = scheme.Value.Properties.Where(p => p.Key.ToLower() == classParameterName.ToLower()).FirstOrDefault();

                    if (swaggerProperty.Key == null || swaggerProperty.Value == null)
                    {
                        continue;
                    }

                    //Nothing is specified for default value, so no attributes to add
                    if (swaggerProperty.Value.Default == null)
                    {
                        continue;
                    }

                    string attributeIdentifierName = string.Empty;

                    if (swaggerProperty.Value.Default != null)
                    {
                        if (swaggerProperty.Value.Default.AnyType == Microsoft.OpenApi.Any.AnyType.Null)
                        {
                            attributeIdentifierName = "DefaultValue(null)";
                        }
                        else
                        {
                            //Additional types could be added here
                            continue;
                        }
                    }

                    var attributeAlreadyExist = classParameter.AttributeLists.Any(a => a.GetText().ToString().Contains("DefaultValue"));

                    if (attributeAlreadyExist)
                    {
                        continue;
                    }

                    var parameterAttributes = classParameter.AttributeLists.Add(
                       SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(
                       SyntaxFactory.Attribute(SyntaxFactory.IdentifierName(attributeIdentifierName))
                    )));

                    dict.Add(classParameter, classParameter.WithAttributeLists(parameterAttributes));
                }
            }

            return root.ReplaceNodes(dict.Keys, (original, rewritten) => dict[original]).NormalizeWhitespace().ToFullString();
        }
    }

【问题讨论】:

    标签: swagger nswag


    【解决方案1】:

    我没有找到单独使用 NSwag 的解决方案。

    因此,我使用了微软的 openapi 包,结合 Roslyn,创建了一个小应用程序,它读取 swagger Json 定义,解析生成的客户端的源代码,并设置默认值属性。

    这很有效,并且提供了相当多的控制,但如果它是 NSwag 中的一个功能,我仍然会更喜欢。

    【讨论】:

    • 您是否有源代码可供他人使用?
    • 我已将来源添加到上述帖子中。随意根据需要进行编辑:-)
    猜你喜欢
    • 2021-11-18
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 2020-04-11
    相关资源
    最近更新 更多