制作自定义Swagger的NuGet包时静态资源加载失败求助
我正在创建一个用于自定义Swagger的NuGet包,核心目标是避免在多个项目中重复复制粘贴Swagger配置及.css、.js文件,使用者只需在AppSettings中配置版本、标题、描述、联系人、安全设置等可变参数即可。但在其他项目中引用该NuGet包时,自定义的swagger-ui/custom.css和swagger-ui/custom.js无法被加载,页面仅显示默认Swagger样式。
相关代码如下:
public static void UseSwagger(this WebApplication? app) { app.UseStaticFiles(); app.UseSwagger(); app.UseSwaggerUI(opt => { opt.DocumentTitle = app.Configuration.GetValue<string>("Swagger:DocumentTitle") ?? "Custom Title Swagger"; opt.InjectStylesheet("/swagger-ui/custom.css"); opt.InjectJavascript("/swagger-ui/custom.js"); }); }
问题根源在于NuGet包中的静态文件默认不会被宿主项目的静态文件中间件识别,需要将这些文件标记为嵌入式资源,并在NuGet包中配置静态文件中间件来读取这些嵌入式资源。
步骤1:将静态文件标记为嵌入式资源
在NuGet包项目中,找到custom.css和custom.js文件,右键选择属性,将生成操作设置为嵌入式资源。同时确保文件的相对路径为swagger-ui/custom.css和swagger-ui/custom.js(可根据项目结构调整)。
步骤2:配置静态文件中间件读取嵌入式资源
修改NuGet包中的UseSwagger扩展方法,添加自定义静态文件提供者以读取嵌入式资源:
using Microsoft.AspNetCore.StaticFiles; using System.Reflection; public static void UseSwagger(this WebApplication? app) { // 获取当前NuGet包的程序集 var assembly = Assembly.GetExecutingAssembly(); // 初始化嵌入式文件提供者,命名空间前缀格式:[项目命名空间].[静态文件所在目录] var provider = new EmbeddedFileProvider(assembly, $"{assembly.GetName().Name}.swagger-ui"); // 配置针对/swagger-ui路径的静态文件访问,优先读取嵌入式资源 app.UseStaticFiles(new StaticFileOptions { FileProvider = provider, RequestPath = "/swagger-ui" }); app.UseSwagger(); app.UseSwaggerUI(opt => { opt.DocumentTitle = app.Configuration.GetValue<string>("Swagger:DocumentTitle") ?? "Custom Title Swagger"; opt.InjectStylesheet("/swagger-ui/custom.css"); opt.InjectJavascript("/swagger-ui/custom.js"); }); }
步骤3:验证命名空间前缀
确保EmbeddedFileProvider的第二个参数是正确的命名空间前缀,格式为[你的NuGet包项目命名空间].[静态文件所在目录]。例如项目命名空间是CustomSwaggerPackage,静态文件放在swagger-ui文件夹下,前缀就是CustomSwaggerPackage.swagger-ui。
你可以通过ILSpy等工具打开编译后的DLL,查看嵌入式资源的完整名称来确认,格式通常为命名空间.目录.文件名。
额外注意事项
- 若宿主项目已调用
app.UseStaticFiles(),无需担心冲突,我们针对/swagger-ui路径单独配置了嵌入式资源提供者,会优先匹配该路径的请求。 - 确保NuGet包项目的
.csproj文件未排除这些静态文件,可显式添加配置:
<ItemGroup> <EmbeddedResource Include="swagger-ui\*.css" /> <EmbeddedResource Include="swagger-ui\*.js" /> </ItemGroup>
内容的提问来源于stack exchange,提问作者SrCabra

