如何让ASP.NET(C#)项目的Swagger UI自动识别无<summary>标签的XML文档注释
如何让ASP.NET(C#)项目的Swagger UI自动识别无标签的XML文档注释
别担心,这个需求完全能搞定!咱们直接上实操步骤,一步一步来:
首先得确保你的项目已经开启了XML文档生成,这是Swagger能读取注释的基础:
- 右键你的项目 → 选择「属性」→ 切换到「生成」标签页
- 找到「输出」区域,勾选「XML文档文件」,默认路径一般是
bin\$(Configuration)\$(AssemblyName).xml,这个路径后面会用到
接下来是关键的一步:自定义一个Swagger操作过滤器,让它自动把没有包裹<summary>标签的注释文本当成summary内容。
咱们写一个过滤器类,比如叫CustomXmlCommentsOperationFilter,实现Swagger的IOperationFilter接口,逻辑就是读取XML注释,要是发现没有<summary>节点,就把注释里的纯文本内容赋给Swagger的接口summary:
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using System.Xml.Linq; using System.Reflection; using System.IO; public class CustomXmlCommentsOperationFilter : IOperationFilter { private readonly XDocument _xmlDocument; // 构造函数注入XML文档对象 public CustomXmlCommentsOperationFilter(XDocument xmlDocument) { _xmlDocument = xmlDocument; } public void Apply(OpenApiOperation operation, OperationFilterContext context) { // 拼接当前方法的XML注释节点名称(格式是M:命名空间.类名.方法名) var methodFullName = $"M:{context.MethodInfo.DeclaringType?.FullName}.{context.MethodInfo.Name}"; var methodCommentNode = _xmlDocument.Descendants("member") .FirstOrDefault(node => node.Attribute("name")?.Value == methodFullName); if (methodCommentNode != null) { // 先检查有没有现成的<summary>节点 var summaryNode = methodCommentNode.Element("summary"); if (summaryNode == null || string.IsNullOrWhiteSpace(summaryNode.Value.Trim())) { // 把member节点下的所有直接文本内容(排除子标签)取出来,作为summary var rawCommentText = string.Join(" ", methodCommentNode.Nodes().OfType<XText>() .Select(text => text.Value.Trim()) .Where(text => !string.IsNullOrWhiteSpace(text))); if (!string.IsNullOrWhiteSpace(rawCommentText)) { operation.Summary = rawCommentText; } } } } }
如果你的模型类(比如DTO)也需要这种自动识别无标签注释的功能,还可以写一个对应的Schema过滤器,逻辑类似,原理就是读取模型类的XML注释节点,把无标签的纯文本自动映射到模型的description上,这里就不展开写了。
最后一步,在Program.cs里注册这个过滤器,同时加载XML文档文件:
var builder = WebApplication.CreateBuilder(args); // 添加控制器服务 builder.Services.AddControllers(); // 配置Swagger服务 builder.Services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo { Title = "你的API名称", Version = "v1" }); // 加载项目生成的XML文档文件 var assemblyName = Assembly.GetExecutingAssembly().GetName().Name; var xmlFilePath = Path.Combine(AppContext.BaseDirectory, $"{assemblyName}.xml"); if (File.Exists(xmlFilePath)) { var xmlDoc = XDocument.Load(xmlFilePath); // 注册咱们自定义的操作过滤器 options.OperationFilter<CustomXmlCommentsOperationFilter>(xmlDoc); // 如果需要处理模型注释,就注册对应的Schema过滤器 // options.SchemaFilter<CustomXmlCommentsSchemaFilter>(xmlDoc); } }); var app = builder.Build(); // 开发环境启用Swagger UI if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
这样配置完之后,你直接写/// List orgs 1 page at a time这种不带<summary>标签的注释,Swagger UI就会自动把这段文本当成接口的summary展示出来啦!
备注:内容来源于stack exchange,提问作者Peter L
相关产品推荐
相关产品推荐

