【发布时间】: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();
}
}
【问题讨论】: