是否有一种方法显示所有枚举作为他们的字符串值在swagger而不是他们的int值?
我希望能够提交POST动作,并根据它们的字符串值放置枚举,而不必每次都查看enum。
我尝试了DescribeAllEnumsAsStrings,但服务器然后接收字符串而不是enum值,这不是我们要寻找的。
有人解决了吗?
编辑:
public class Letter
{
[Required]
public string Content {get; set;}
[Required]
[EnumDataType(typeof(Priority))]
public Priority Priority {get; set;}
}
public class LettersController : ApiController
{
[HttpPost]
public IHttpActionResult SendLetter(Letter letter)
{
// Validation not passing when using DescribeEnumsAsStrings
if (!ModelState.IsValid)
return BadRequest("Not valid")
..
}
// In the documentation for this request I want to see the string values of the enum before submitting: Low, Medium, High. Instead of 0, 1, 2
[HttpGet]
public IHttpActionResult GetByPriority (Priority priority)
{
}
}
public enum Priority
{
Low,
Medium,
High
}
使全球
从文档中可以看出:
httpConfiguration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "A title for your API");
c.DescribeAllEnumsAsStrings(); // this will do the trick
});
特定属性的Enum/字符串转换
另外,如果你想让这种行为只发生在特定的类型和属性上,使用StringEnumConverter:
public class Letter
{
[Required]
public string Content {get; set;}
[Required]
[EnumDataType(typeof(Priority))]
[JsonConverter(typeof(StringEnumConverter))]
public Priority Priority {get; set;}
}
如果你使用的是Newtonsoft和Swashbuckle v5.0.0或更高版本
你还需要这个包:
Swashbuckle.AspNetCore.Newtonsoft
在你的创业公司里:
services.AddSwaggerGenNewtonsoftSupport(); // explicit opt-in - needs to be placed after AddSwaggerGen()
这里有文档:https://github.com/domaindrivendev/Swashbuckle.AspNetCore#systemtextjson-stj-vs-newtonsoft
在。net 6与NSwag和System.Text.Json为我工作:
services.AddControllersWithViews()
.AddJsonOptions(o => o.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()))
and
services.AddOpenApiDocument(configure =>
{
...
configure.GenerateEnumMappingDescription = true;
});
它接受int-s和字符串,在open-api和.ts客户端生成带有名称的枚举,并在SwaggerUI中显示带有名称的枚举
export enum PaymentDirection {
Input = "Input",
Output = "Output",
}
我得到了它的工作。net 6 Web API使用以下代码从其他答案在这里:
1 -创建一个DocumentFilter
/// <summary>
/// Add enum value descriptions to Swagger
/// </summary>
public class SwaggerEnumDocumentFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
// add enum descriptions to result models
foreach (var property in swaggerDoc.Components.Schemas)
{
var propertyEnums = property.Value.Enum;
if (propertyEnums is { Count: > 0 })
{
property.Value.Description += DescribeEnum(propertyEnums, property.Key);
}
}
if (swaggerDoc.Paths.Count <= 0)
{
return;
}
// add enum descriptions to input parameters
foreach (var pathItem in swaggerDoc.Paths.Values)
{
DescribeEnumParameters(pathItem.Parameters);
var affectedOperations = new List<OperationType> { OperationType.Get, OperationType.Post, OperationType.Put, OperationType.Patch };
foreach (var operation in pathItem.Operations)
{
if (affectedOperations.Contains(operation.Key))
{
DescribeEnumParameters(operation.Value.Parameters);
}
}
}
}
private static void DescribeEnumParameters(IList<OpenApiParameter> parameters)
{
if (parameters == null) return;
foreach (var param in parameters)
{
if (param.Schema.Reference != null)
{
var enumType = GetEnumTypeByName(param.Schema.Reference.Id);
var names = Enum.GetNames(enumType).ToList();
param.Description += string.Join(", ", names.Select(name => $"{Convert.ToInt32(Enum.Parse(enumType, name))} - {name}").ToList());
}
}
}
private static Type GetEnumTypeByName(string enumTypeName)
{
if (string.IsNullOrEmpty(enumTypeName))
{
return null;
}
try
{
return AppDomain.CurrentDomain
.GetAssemblies()
.SelectMany(x => x.GetTypes())
.Single(x => x.FullName != null
&& x.Name == enumTypeName);
}
catch (InvalidOperationException e)
{
throw new Exception($"SwaggerDoc: Can not find a unique Enum for specified typeName '{enumTypeName}'. Please provide a more unique enum name.");
}
}
private static string DescribeEnum(IEnumerable<IOpenApiAny> enums, string propertyTypeName)
{
var enumType = GetEnumTypeByName(propertyTypeName);
if (enumType == null)
{
return null;
}
var parsedEnums = new List<OpenApiInteger>();
foreach (var @enum in enums)
{
if (@enum is OpenApiInteger enumInt)
{
parsedEnums.Add(enumInt);
}
}
return string.Join(", ", parsedEnums.Select(x => $"{x.Value} - {Enum.GetName(enumType, x.Value)}"));
}
}
2 -将其添加到Program.cs文件中
services.AddSwaggerGen(config =>
{
config.DocumentFilter<SwaggerEnumDocumentFilter>();
})
asp.net core 3
using System.Text.Json.Serialization;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers().AddJsonOptions(options =>
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));
但是Swashbuckle Version 5.0.0-rc4似乎还没有准备好支持这个功能。所以我们需要在Swashbuckle配置文件中使用一个选项(已弃用),直到它像Newtonsoft库一样支持和反映它。
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
c.DescribeAllEnumsAsStrings();
这个答案和其他答案之间的区别是只使用Microsoft JSON库而不是Newtonsoft。
在。net core 3.1和swagger 5.0.0中:
using System.Linq;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace WebFramework.Swagger
{
public class EnumSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (context.Type.IsEnum)
{
var enumValues = schema.Enum.ToArray();
var i = 0;
schema.Enum.Clear();
foreach (var n in Enum.GetNames(context.Type).ToList())
{
schema.Enum.Add(new OpenApiString(n + $" = {((OpenApiPrimitive<int>)enumValues[i]).Value}"));
i++;
}
}
}
}
}
在Startup.cs中:
services.AddSwaggerGen(options =>
{
#region EnumDesc
options.SchemaFilter<EnumSchemaFilter>();
#endregion
});