如何定义从以下 API 生成的 swagger 中的属性的默认值?
public class SearchQuery
{
public string OrderBy { get; set; }
[DefaultValue(OrderDirection.Descending)]
public OrderDirection OrderDirection { get; set; } = OrderDirection.Descending;
}
public IActionResult SearchPendingCases(SearchQuery queryInput);
Swashbuckle 生成 OrderDirection 作为必需参数。我希望它是可选的,并向客户端指示默认值(不确定 swagger 是否支持这一点)。
我不喜欢使属性类型可为空。还有其他选择吗?理想情况下使用内置类...
我使用 Swashbuckle.AspNetCore - https://learn.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger?tabs=visual-studio
我总是像这样设置参数本身的默认值:
public class TestPostController : ApiController
{
public decimal Get(decimal x = 989898989898989898, decimal y = 1)
{
return x * y;
}
}
这是 swagger-ui 上的样子:
http://swashbuckletest.azurewebsites.net/swagger/ui/index#/TestPost/TestPost_Get
在对评论进行讨论后,我更新了 Swagger-Net 以通过反射阅读
DefaultValueAttribute
这是我正在使用的示例类:
public class MyTest
{
[MaxLength(250)]
[DefaultValue("HelloWorld")]
public string Name { get; set; }
public bool IsPassing { get; set; }
}
这是 swagger json 的样子:
"MyTest": {
"type": "object",
"properties": {
"Name": {
"default": "HelloWorld",
"maxLength": 250,
"type": "string"
},
"IsPassing": {
"type": "boolean"
}
},
"xml": {
"name": "MyTest"
}
},
Swagger-Net的源代码在这里:
https://github.com/heldersepu/Swagger-Net
测试项目的源代码在这里:
https://github.com/heldersepu/SwashbuckleTest
如果您可以在控制器中设置默认参数值,则可以像这样工作
// GET api/products
[HttpGet]
public IEnumerable<Product> Get(int count = 50)
{
Conn mySqlGet = new Conn(_connstring);
return mySqlGet.ProductList(count);
}
这适用于 ASP.net MVC5,代码对 .Net Core 无效
1- 定义自定义属性如下
public class SwaggerDefaultValueAttribute: Attribute
{
public SwaggerDefaultValueAttribute(string param, string value)
{
Parameter = param;
Value = value;
}
public string Parameter {get; set;}
public string Value {get; set;}
}
2- 定义 Swagger OperationFilter 类
public class AddDefaulValue: IOperationFilter
{
void IOperationFilter.Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
if (operation.parameters == null || !operation.parameters.Any())
{
return;
}
var attributes = apiDescription.GetControllerAndActionAttributes<SwaggerDefaultValueAttribute>().ToList();
if (!attributes.Any())
{
return;
}
foreach(var parameter in operation.parameters)
{
var attr = attributes.FirstOrDefault(it => it.Parameter == parameter.name);
if(attr != null)
{
parameter.@default = attr.Value;
}
}
}
}
3- 在 SwaggerConfig 文件中注册 OperationFilter
c.OperationFilter<AddDefaultValue>();
4-用属性装饰你的控制器方法
[SwaggerDefaultValue("param1", "AnyValue")]
public HttpResponseMessage DoSomething(string param1)
{
return Request.CreateResponse(HttpStatusCode.OK);
}
根据答案之一here,您应该能够简单地将以下内容添加到您的模型中,尽管我尚未验证这一点:
public class ExternalJobCreateViewModel
{
///<example>Bob</example>
public string CustomFilename { get; set; }
...etc
在 .net 6 中我使用了以下内容:
public class MyFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.OperationId.Equals("somecontroller_somepath", StringComparison.OrdinalIgnoreCase))
{
operation.Parameters.Clear();
operation.Parameters = new List<OpenApiParameter>
{
new OpenApiParameter()
{
Name = "document-name",
Schema = new OpenApiSchema()
{
Type = "string",
},
Example = new Microsoft.OpenApi.Any.OpenApiString("docName1"),
In = ParameterLocation.Query
},
new OpenApiParameter()
{
Name = "user-email",
Schema = new OpenApiSchema()
{
Type = "string",
},
Example = new Microsoft.OpenApi.Any.OpenApiString("[email protected]"),
In = ParameterLocation.Query
},
new OpenApiParameter()
{
Name = "account-type-id",
Schema = new OpenApiSchema()
{
Type = "string",
},
Example = new Microsoft.OpenApi.Any.OpenApiString("2"),
In = ParameterLocation.Query
}
};
}
}
}
然后在Program.cs中
builder.Services.AddSwaggerGen(options =>
{
... other stuf
options.OperationFilter<MyFilter>();
我从未使用过此代码,因此未测试
在 .net 6 中并搭载 Sameh 的答案...
要使用多个属性,请像这样装饰属性类:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class SwaggerDefaultValueAttribute : Attribute
{
... etc
对于 6.5.0 的 swashbuckle,我认为属性是这样的:
public class AddDefaulValueFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Parameters == null || !operation.Parameters.Any())
{
return;
}
context.ApiDescription.TryGetMethodInfo(out var x);
if (x != null)
{
return;
}
var attributes = x!.GetCustomAttributes<SwaggerDefaultValueAttribute>().ToList();
if (!attributes.Any())
{
return;
}
foreach (var parameter in operation.Parameters)
{
var attr = attributes.FirstOrDefault(it => it.Parameter == parameter.Name);
if (attr != null)
{
parameter.Schema.Default = new OpenApiString(attr.Value);
}
}
}
}
由于我试图将其用于多部分消息的正文参数,因此我必须执行类似的操作,但使用风险自负:
public class AddDefaulValueFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if(operation.RequestBody == null)
{
return;
}
var keys = operation.RequestBody.Content.Where(val => val.Key == "multipart/form-data").Take(1).ToList();
if(!keys.Any())
{
return;
}
var props = keys.FirstOrDefault().Value.Schema.Properties;
if (props == null || !props.Any())
{
return;
}
context.ApiDescription.TryGetMethodInfo(out var x);
if (x == null)
{
return;
}
var attributes = x!.GetCustomAttributes<SwaggerDefaultValueAttribute>().ToList();
if (!attributes.Any())
{
return;
}
foreach (var prop in props)
{
var attr = attributes.FirstOrDefault(it => it.Parameter == prop.Key);
if (attr != null)
{
prop.Value.Default = new OpenApiString(attr.Value);
}
}
}
}
这就是我的做法(使用.Net Core 7.0,可能适用于旧版本):
控制器声明(示例):
[HttpGet("DynValuesCycleGensetPerMicrogridAndDate")]
public async Task<ActionResult<DynamicValuesByMicrogridDto>> DynValuesCycleGensetPerMicrogridAndDate(
[SwaggerTryItOutDefaulValue("1")] int microgridId,
[SwaggerTryItOutDefaulValue("2023-10-07 15:00")] DateTimeOffset dateTimeStart,
[SwaggerTryItOutDefaulValue("2023-10-09 15:00")] DateTimeOffset dateTimeEnd)
{
//...
程序初始化:
builder.Services.AddSwaggerGen(options =>
{
options.SchemaFilter<SwaggerTryItOutDefaulValue>();
//...
ISchemaFilter:
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;
namespace GeneralAsp
{
public class SwaggerTryItOutDefaulValue : ISchemaFilter
{
/// <summary>
/// Apply is called for each parameter
/// </summary>
/// <param name="schema"></param>
/// <param name="context"></param>
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (context.ParameterInfo != null)
{
var att = context.ParameterInfo.GetCustomAttribute<SwaggerTryItOutDefaulValueAttribute>();
if ((att != null))
{
schema.Example = new Microsoft.OpenApi.Any.OpenApiString(att.Value.ToString());
}
}
}
}
}
属性:
namespace GeneralAsp
{
public class SwaggerTryItOutDefaulValueAttribute : Attribute
{
public string Value { get; }
public SwaggerTryItOutDefaulValueAttribute(string value)
{
Value = value;
}
}
}
在 YAML 文件中,您可以定义需要哪些属性。此示例来自 NSwag 配置。
/SearchPendingCases:
post:
summary: Search pending cases
description: Searches for pending cases and orders them
parameters:
- in: body
name: SearchQuery
required: true
schema:
type: object
required:
- OrderBy
# do not include OrderDirection here because it is optional
properties:
OrderBy:
description: Name of property for ordering
type: string
# you can remove the following two lines
# if you do not want to check the string length
minLength: 1
maxLength: 100
OrderDirection:
description: Optional order direction, default value: Descending
type: string
enum: [Ascending, Descending] # valid enum values
default: Descending # default value