是否有一种方法显示所有枚举作为他们的字符串值在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
}
我想在. net Core应用程序中使用rory_za的答案,但我必须对其进行一些修改才能使其工作。下面是我为。net Core设计的实现。
我还修改了它,这样它就不会假设底层类型是int,并在值之间使用了新的行,以便于阅读。
/// <summary>
/// Add enum value descriptions to Swagger
/// </summary>
public class EnumDocumentFilter : IDocumentFilter {
/// <inheritdoc />
public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context) {
// add enum descriptions to result models
foreach (var schemaDictionaryItem in swaggerDoc.Definitions) {
var schema = schemaDictionaryItem.Value;
foreach (var propertyDictionaryItem in schema.Properties) {
var property = propertyDictionaryItem.Value;
var propertyEnums = property.Enum;
if (propertyEnums != null && propertyEnums.Count > 0) {
property.Description += DescribeEnum(propertyEnums);
}
}
}
if (swaggerDoc.Paths.Count <= 0) return;
// add enum descriptions to input parameters
foreach (var pathItem in swaggerDoc.Paths.Values) {
DescribeEnumParameters(pathItem.Parameters);
// head, patch, options, delete left out
var possibleParameterisedOperations = new List<Operation> {pathItem.Get, pathItem.Post, pathItem.Put};
possibleParameterisedOperations.FindAll(x => x != null)
.ForEach(x => DescribeEnumParameters(x.Parameters));
}
}
private static void DescribeEnumParameters(IList<IParameter> parameters) {
if (parameters == null) return;
foreach (var param in parameters) {
if (param is NonBodyParameter nbParam && nbParam.Enum?.Any() == true) {
param.Description += DescribeEnum(nbParam.Enum);
} else if (param.Extensions.ContainsKey("enum") && param.Extensions["enum"] is IList<object> paramEnums &&
paramEnums.Count > 0) {
param.Description += DescribeEnum(paramEnums);
}
}
}
private static string DescribeEnum(IEnumerable<object> enums) {
var enumDescriptions = new List<string>();
Type type = null;
foreach (var enumOption in enums) {
if (type == null) type = enumOption.GetType();
enumDescriptions.Add($"{Convert.ChangeType(enumOption, type.GetEnumUnderlyingType())} = {Enum.GetName(type, enumOption)}");
}
return $"{Environment.NewLine}{string.Join(Environment.NewLine, enumDescriptions)}";
}
}
然后将它添加到Startup.cs中的ConfigureServices方法中:
c.DocumentFilter<EnumDocumentFilter>();
如果有人感兴趣,我已经修改了代码的工作
.NET CORE 3和Swagger V5
public class SwaggerAddEnumDescriptions : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
// add enum descriptions to result models
foreach (var property in swaggerDoc.Components.Schemas.Where(x => x.Value?.Enum?.Count > 0))
{
IList<IOpenApiAny> propertyEnums = property.Value.Enum;
if (propertyEnums != null && propertyEnums.Count > 0)
{
property.Value.Description += DescribeEnum(propertyEnums, property.Key);
}
}
// add enum descriptions to input parameters
foreach (var pathItem in swaggerDoc.Paths.Values)
{
DescribeEnumParameters(pathItem.Operations, swaggerDoc);
}
}
private void DescribeEnumParameters(IDictionary<OperationType, OpenApiOperation> operations, OpenApiDocument swaggerDoc)
{
if (operations != null)
{
foreach (var oper in operations)
{
foreach (var param in oper.Value.Parameters)
{
var paramEnum = swaggerDoc.Components.Schemas.FirstOrDefault(x => x.Key == param.Name);
if (paramEnum.Value != null)
{
param.Description += DescribeEnum(paramEnum.Value.Enum, paramEnum.Key);
}
}
}
}
}
private Type GetEnumTypeByName(string enumTypeName)
{
return AppDomain.CurrentDomain
.GetAssemblies()
.SelectMany(x => x.GetTypes())
.FirstOrDefault(x => x.Name == enumTypeName);
}
private string DescribeEnum(IList<IOpenApiAny> enums, string proprtyTypeName)
{
List<string> enumDescriptions = new List<string>();
var enumType = GetEnumTypeByName(proprtyTypeName);
if (enumType == null)
return null;
foreach (IOpenApiAny enumOption in enums)
{
if (enumOption is OpenApiString @string)
{
string enumString = @string.Value;
enumDescriptions.Add(string.Format("{0} = {1}", (int)Enum.Parse(enumType, enumString), enumString));
}
else if (enumOption is OpenApiInteger integer)
{
int enumInt = integer.Value;
enumDescriptions.Add(string.Format("{0} = {1}", enumInt, Enum.GetName(enumType, enumInt)));
}
}
return string.Join(", ", enumDescriptions.ToArray());
}
}