.net core Swashbuckle( swagger) 枚举显示值改成显示枚举属性,以及枚举描述

本文介绍如何在ASP.NET Core中将枚举值转换为枚举属性,并展示如何通过两种方式实现这一功能。此外,还提供了两种方法来在Swagger文档中正确显示枚举的描述。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

只要在你的ConfigureServices中添加如下代码(两种方案都行)即可:

原创不易转载请注明转载地址,谢谢!

一、把枚举值改成枚举属性 

//方法一
services.AddMvc(option => option.EnableEndpointRouting = false).AddJsonOptions(options =>{
    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
//方法二
services.AddControllers().AddJsonOptions(options =>
            options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));

没改之前

改了之后

枚举

public enum UserType
    {
        /// <summary>
        /// 超级管理员
        /// </summary>
        [Description("超级管理员")]
        Administrator = 1,
        /// <summary>
        /// 高级管理员
        /// </summary>
        [Description("管理员")]
        Admin = 2,
        /// <summary>
        /// 用户
        /// </summary>
        [Description("用户")]
        User = 3
    }

二、显示枚举描述

注意:里面的GetDescription方法时扩展方法,放在了后面

方法一:添加SwaggerEnumFilter类,继承IDocumentFilter,代码如下

using Microsoft.OpenApi.Any;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;

namespace DotNetCoreApi.Filter
{
    /// <summary>
    /// swagger文档生成过滤器,用于枚举描述的生成
    /// </summary>
    public class SwaggerEnumFilter : IDocumentFilter
    {
        /// <summary>
        /// 实现IDocumentFilter接口的Apply函数
        /// </summary>
        /// <param name="swaggerDoc"></param>
        /// <param name="context"></param>
        public void Apply(Microsoft.OpenApi.Models.OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            Dictionary<string, Type> dict = GetAllEnum();

            foreach (var item in swaggerDoc.Components.Schemas)
            {
                var property = item.Value;
                var typeName = item.Key;
                Type itemType = null;
                if (property.Enum != null && property.Enum.Count > 0)
                {
                    if (dict.ContainsKey(typeName))
                    {
                        itemType = dict[typeName];
                    }
                    else
                    {
                        itemType = null;
                    }
                    List<OpenApiInteger> list = new List<OpenApiInteger>();
                    foreach (var val in property.Enum)
                    {
                        list.Add((OpenApiInteger)val);
                    }
                    property.Description += DescribeEnum(itemType, list);
                }
            }
        }
        private static Dictionary<string, Type> GetAllEnum()
        {
            Assembly ass = Assembly.Load("Model");//枚举所在的命名空间的xml文件名,我的枚举都放在Model层里(类库)
            Type[] types = ass.GetTypes();
            Dictionary<string, Type> dict = new Dictionary<string, Type>();

            foreach (Type item in types)
            {
                if (item.IsEnum)
                {
                    dict.Add(item.Name, item);
                }
            }
            return dict;
        }

        private static string DescribeEnum(Type type, List<OpenApiInteger> enums)
        {
            var enumDescriptions = new List<string>();
            foreach (var item in enums)
            {
                if (type == null) continue;
                var value = Enum.Parse(type, item.Value.ToString());
                var desc = GetDescription(type, value);

                if (string.IsNullOrEmpty(desc))
                    enumDescriptions.Add($"{item.Value.ToString()}:{Enum.GetName(type, value)};");
                else
                    enumDescriptions.Add($"{item.Value.ToString()}:{Enum.GetName(type, value)},{desc};");
            }
            return $"<br><div>{Environment.NewLine}{string.Join("<br/>" + Environment.NewLine, enumDescriptions)}</div>";
        }

        private static string GetDescription(Type t, object value)
        {
            foreach (MemberInfo mInfo in t.GetMembers())
            {
                if (mInfo.Name == t.GetEnumName(value))
                {
                    foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo))
                    {
                        if (attr.GetType() == typeof(DescriptionAttribute))
                        {
                            return ((DescriptionAttribute)attr).Description;
                        }
                    }
                }
            }
            return string.Empty;
        }
    }
}

注册服务:在Startup中的ConfigureServices添加注册,如下

 services.AddSwaggerGen(c =>
{
    //省略其他代码
    c.DocumentFilter<SwaggerEnumFilter>();
}

 

这种方法显示枚举描述如下

枚举如下

namespace Model.Enum
{
    /// <summary>
    /// 用户类型枚举
    /// </summary>

    public enum UserType
    {
        /// <summary>
        /// 超级管理员
        /// </summary>
        [Description("超级管理员")]
        Administrator = 1,
        /// <summary>
        /// 高级管理员
        /// </summary>
        [Description("管理员")]
        Admin = 2,
        /// <summary>
        /// 用户
        /// </summary>
        [Description("用户")]
        User = 3
    }
}

方法二:添加EnumSchemaFilter 类,实现 ISchemaFilter 接口,代码如下:

using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Util.Expand;

namespace DotNetCoreApi.Filter
{
    /// <summary>
    /// Swagger文档枚举字段显示枚举属性和枚举值,以及枚举描述
    /// </summary>
    public class EnumSchemaFilter : ISchemaFilter
    {
        /// <summary>
        /// 实现接口
        /// </summary>
        /// <param name="model"></param>
        /// <param name="context"></param>

        public void Apply(OpenApiSchema model, SchemaFilterContext context)
        {
            if (context.Type.IsEnum)
            {
                model.Enum.Clear();
                Enum.GetNames(context.Type)
                    .ToList()
                    .ForEach(name =>
                    {
                        Enum e = (Enum)Enum.Parse(context.Type, name);
                        model.Enum.Add(new OpenApiString($"{name}({e.GetDescription()})={Convert.ToInt64(Enum.Parse(context.Type, name))}"));
                    });
            }
        }

    }
}

 在Startup中的ConfigureServices添加注册,如下

 services.AddSwaggerGen(c =>
{
    //省略其他代码
    c.SchemaFilter<EnumSchemaFilter>();
}

效果如下:

到此结束...

### 如何在 .NET Core 中使用 Swagger 和 Controller 实现数据库访问 #### 配置 Swagger 文档支持枚举成员描述 为了使 API 请求和响应模型中的枚举成员能够带有详细的说明,在配置 `Swashbuckle.AspNetCore` 时可以自定义文档过滤器来处理这些细节[^1]。 ```csharp services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); // 添加此行以启用 XML 注释文件的支持 var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); // 自定义过滤器用于解析并显示枚举的注释信息 c.MapType<DayOfWeek>(() => new OpenApiSchema { Type = "string", Enum = typeof(DayOfWeek).GetFields(BindingFlags.Public | BindingFlags.Static).Select(f => (long)f.GetRawConstantValue()).ToList() }); }); ``` #### 启用 Swagger 并设置分组 通过修改应用程序配置文件(如 `appsettings.json` 或者 `.ini` 文件),可控制是否开启 Swagger UI 及其展示方式。这里展示了如何利用 INI 格式的配置项管理多个 API 组以及开关状态[^2]: ```ini [system] ApiGroup=[ {"en":"group1","cn":"测试组一"}, {"en":"group2","cn":"测试组二"}, {"en":"WeatherForecast","cn":"气象服务"} ] EnableSwagger=1 ``` 当读取上述配置后,可以在启动类中依据设定动态调整中间件行为: ```csharp if(Configuration.GetValue<int>("system:EnableSwagger") == 1){ app.UseSwagger(); app.UseSwaggerUI(options => { foreach(var group in Configuration.GetSection("system:ApiGroup").Get<List<Dictionary<string,string>>>()){ options.SwaggerEndpoint($"/swagger/{group["en"]}/swagger.json", group["cn"]); } }); } ``` #### 创建控制器并与数据源交互 下面是一个简单的例子,它创建了一个名为 `ItemsController` 的 RESTful Web API 控制器,并连接到内存数据库获取或保存项目列表的数据记录。 首先安装必要的 NuGet 包: - Microsoft.EntityFrameworkCore.InMemory - Swashbuckle.AspNetCore 接着定义实体类及其对应的 DbContext 类型: ```csharp public class Item { public int Id { get; set; } /// <summary> /// 商品名称. /// </summary> [Required] public string Name { get; set; } /// <summary> /// 单价(). /// </summary> [Range(0,double.MaxValue)] public decimal Price { get; set; } } public class AppDbContext : DbContext { public DbSet<Item> Items { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseInMemoryDatabase(databaseName:"TestDb"); } ``` 最后编写具体的 HTTP 方法实现增删改查功能: ```csharp [ApiController] [Route("[controller]")] public class ItemsController : ControllerBase { private readonly AppDbContext _context; public ItemsController(AppDbContext context) => _context = context; // GET /items [HttpGet(Name="GetAll")] public async Task<ActionResult<IEnumerable<ItemDTO>>> Get() { return Ok(await _context.Items.Select(i=>new ItemDTO{Id=i.Id,Name=i.Name}).ToListAsync()); } // POST /items [HttpPost(Name ="CreateItem")] public async Task<IActionResult> Post([FromBody] CreateItemCommand command) { await _context.Items.AddAsync(new Item{Name=command.Name,Price=command.Price}); await _context.SaveChangesAsync(); return CreatedAtAction(nameof(Get),new{id=_context.Items.LastOrDefault()?.Id},null); } } ``` 以上代码片段实现了基本 CRUD 操作的同时也集成了 Swagger 自动生成接口文档的功能,方便开发者调试API端点。
评论 135
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小星博博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值