C# Swagger: 指定一个固定的字符串数组作为请求体参数。

huangapple go评论69阅读模式
英文:

C# Swagger: Specify a Fixed Array of Strings as Body Parameters

问题

In a dotnet project, I'm trying to list the possible values for a parameter to be able to just select it in a dropdown, but currently, the parameter is listed as object (query) but instead, it should be a string type.

the code:

c.OperationFilter<SwaggerExt>();

{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (operation.Parameters == null)
            return;

        foreach (var parameter in operation.Parameters)
        {
            if (parameter.Name == "P1")
            {
                parameter.Schema = new OpenApiSchema
                {
                    Type = "object",
                    Properties = new Dictionary<string, OpenApiSchema>
                    {
                        {
                            "P1",
                            new OpenApiSchema
                            {
                                Type = "string",
                                Enum = new List<IOpenApiAny>
                                {
                                    new OpenApiString("value-1"),
                                    new OpenApiString("value-2"),
                                    new OpenApiString("value-3")
                                }
                            }
                        }
                    }
                };
            }
        }
    }
}```

<details>
<summary>英文:</summary>

In a dotnet project i&#39;m trying to list the possible values for a parameter to be able to just select it in dropdown.

but currently the parameter is listed as **object** *(query)* but instead it should be a string type

the code: 


``` c.OperationFilter&lt;SwaggerExt&gt;();``` 


public class SwaggerExt : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Parameters == null)
return;

    foreach (var parameter in operation.Parameters)
    {
        if (parameter.Name == &quot;P1&quot;)
        {
            parameter.Schema = new OpenApiSchema
            {
                Type = &quot;object&quot;,
                Properties = new Dictionary&lt;string, OpenApiSchema&gt;
                {
                    {
                        &quot;P1&quot;,
                        new OpenApiSchema
                        {
                            Type = &quot;string&quot;,
                            Enum = new List&lt;IOpenApiAny&gt;
                            {
                                new OpenApiString(&quot;value-1&quot;),
                                new OpenApiString(&quot;value-2&quot;),
                                new OpenApiString(&quot;value-3&quot;)
                            }
                        }
                    }
                }
            };
        }
    }
}

}


</details>


# 答案1
**得分**: 1

根据@Helen的评论,这是问题的一部分,所以我做的解决方法是将类型从**Object**更改为**Array**,然后在**Items**中定义列表。

因此,为了在Swagger中为特定参数定义一个字符串数组,我做了以下操作:

我还需要从另一个服务中使值动态化:有多种方法可以实现这一点,你可以创建一个构造函数,并只注入列表,或者通过在操作过滤器中注入`IYourService`来管理它。

```csharp
public class SwaggerCustomsFilter : IOperationFilter
{
    private readonly IHttpContextAccessor _contextAccessor;
    
    public SwaggerCustomsFilter(IHttpContextAccessor contextAccessor)
    {
        _contextAccessor = contextAccessor;
    }

    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (operation.Parameters == null)
            return;

        foreach (var parameter in operation.Parameters)
        {
            if (parameter.Name == "ParameterName")
            {
                var test = _contextAccessor.HttpContext.RequestServices.GetRequiredService<IYourService>();
                var values = test.GetValues();

                parameter.Schema = new OpenApiSchema
                {
                    Type = "array",
                    Items = new OpenApiSchema
                    {
                        Type = "string",
                        Enum = new List<IOpenApiAny>(values.Select(v => new OpenApiString(v)).ToList())
                    }
                };
            }
        }
    }
}

注意

如果您的参数不是数组,请尝试像@Helen在截图中提到的这样操作:

if (parameter.Name == "P1")
{
    parameter.Schema = new OpenApiSchema
    {
        Type = "string",
        Enum = new List<IOpenApiAny>
        {
            new OpenApiString("value-1"),
            new OpenApiString("value-2"),
            new OpenApiString("value-3")
        }
    };
}
英文:

Based on @Helen comment, that was part of the issue,

so what i did to solve this problem is to change the type from an Object to an Array and then define the list inside the Items.

So in order to define an Array of String for a specific parameter in Swagger here is what i did:

I needed also to make the values dynamic from another service: there are multiple ways to achieve this, you can make a constructor and inject only the list or manage it inside the OperationFilter by injecting IYourService

public class SwaggerCustomsFilter : IOperationFilter
{
    private readonly IHttpContextAccessor _contextAccessor;
    
    public SwaggerCustomsFilter(IHttpContextAccessor contextAccessor)
    {
        _contextAccessor = contextAccessor;
    }

    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (operation.Parameters == null)
            return;

        //
        // Use Linq: firstOrDefault to optimize the foreach loop and check if parameter is not null
        //
        foreach (var parameter in operation.Parameters)
        {
            if (parameter.Name == &quot;ParameterName&quot;)
            {
                var test = _contextAccessor.HttpContext.RequestServices.GetRequiredService&lt;IYourService&gt;();
                var values = test.GetValues();

                parameter.Schema = new OpenApiSchema
                {
                    Type = &quot;array&quot;,
                    Items = new OpenApiSchema
                    {
                        Type = &quot;string&quot;,
                        Enum = new List&lt;IOpenApiAny&gt;(values.Select(v =&gt; new OpenApiString(v)).ToList())
                    }
                };
            }
        }
    }
}

Note

if your parameter is not an array try what @helen mentioned in the screenshot like this:

if (parameter.Name == &quot;P1&quot;)
{
    parameter.Schema = new OpenApiSchema
    {
        Type = &quot;string&quot;,
        Enum = new List&lt;IOpenApiAny&gt;
        {
            new OpenApiString(&quot;value-1&quot;),
            new OpenApiString(&quot;value-2&quot;),
            new OpenApiString(&quot;value-3&quot;)
        }
    };
}

huangapple
  • 本文由 发表于 2023年6月27日 20:30:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76564892.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定