这是 .NET Core 3.1 上的 ASP.NET MVC 应用程序,带有 Swashbuckle.AspNetCore 6.1.4(最新)。当我尝试在
/swagger/index.html
加载 Swagger UI 时,收到 404。看来 Swagger 中间件没有处理请求,而是转而访问静态文件中间件。令人愤怒的是,这曾经工作得很好,但我无法弄清楚我最近所做的更改会导致这个问题。
我的 Startup.cs 文件有这个(相当标准):
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.RoutePrefix = "swagger";
options.SwaggerEndpoint($"{SWAGGER_VERSION}/swagger.json", "My API");
options.EnableDeepLinking();
});
app.UseStaticFiles();
当我注意到 404 发生时,我尝试在浏览器中加载 JSON 文件,但得到了 IIS Express 404 页面,其中有一些奇怪的东西。尽管 HTTP 请求是针对
swagger.json
,但错误页面显示:
Requested URL: https://localhost:44316/wwwroot/swagger/v1/swagger.js
Physical path: C:\Users\hcheng\source\repos\[xxx]\src\[xxx.yyyy]\wwwroot\swagger\v1\swagger.js
于是IIS更改了文件扩展名,然后尝试在
wwwroot
文件夹中查找不存在的Javascript文件。请注意,我也有 URL 重写,但我的重写规则都不适用于此(我什至完全注释掉了它,这没有改变任何内容)。
我能够通过将端点更改为
swaggerjson
来解决这个问题,效果很好。但是,这并没有解决 index.html
的 404 问题。对于这个,它是类似的:
Requested URL: https://localhost:44316/wwwroot/swagger/index.html
Physical path: C:\Users\hcheng\source\repos\[xxx]\src\[xxx.yyyy]\wwwroot\swagger\index.html
我在管道中添加了一些虚拟中间件,如下所示:
app.UseSwagger(); // options omitted
app.UseSwaggerUI(); // options omitted
app.Use(async (context, next) => await next()); // breakpoint here
app.UseStaticFiles();
app.Use(async (context, next) => await next()); // breakpoint here
现在,当我尝试加载
/swagger/index.html
时,我遇到了第一个断点,但没有遇到第二个断点,这证实了我的理论:Swagger 中间件没有处理请求,而是静态文件在处理请求。
更新:事实证明,当我遇到这些断点时,请求实际上是针对
favicon.ico
;对 /swagger/index/html
的请求根本没有命中这些,这意味着 IIS 在这里完全绕过了 ASP.NET。
我真的不知道我做了什么让这不起作用。这种行为最初是在我安装了 Swashbuckle 5.6.3 时开始出现的,但即使在升级到 6.1.4 后,这种情况仍然存在。
这个问题也扩展到了我的 ElmahCore 实现,这表明这可能是一个更大的问题。对于 Elmah,CSS 和 JS 请求也是 404,而且处理这些请求的是静态文件中间件,而不是 Elmah 中间件。
任何帮助将不胜感激。
事实证明这实际上不是代码问题,而是配置问题。我是对的;最近的一个变化导致了这个问题。它于上周首次部署,在 IIS 中进程内运行。因此,这需要一个 web.config 文件,我从我们的另一个网站复制了该文件。在该文件中,它拦截静态资产(图像、样式表、HTML 文件)的请求并直接从 IIS 提供服务,因此这意味着 Swagger 中间件甚至没有接收请求(这同样适用于 Elmah)。
<system.webServer>
<handlers>
<add name="StaticFileModuleHtml" path="*.html" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<add name="StaticFileModuleHtm" path="*.htm" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<add name="StaticFileModuleSvg" path="*.svg" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<add name="StaticFileModuleJs" path="*.js" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
[etc]
我只需要把这些注释掉,一切就恢复正常了。尤里卡时刻来自阅读 https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-5.0#serve-files-from-multiple-locations 其中指出“如果 IIS 静态文件处理程序已启用并且 ASP.NET Core 模块配置不正确,提供静态文件。”
此外,我在部署到 IIS 时遇到了一个问题,当生成 Swagger 文件夹时,生成了一个 web.config,这导致我的页面出现错误。
web.config 是由我的托管提供商生成的。如果有人不知道出了什么问题,请检查 web.config 是否在您的 swagger 或 index.html 文件夹中。
在 .Net6 及更高版本中,您需要这样做,否则 Swagger 将无法访问您运行的 API:
app.MapControllers();
在您的
ConfigureServices()
方法(也在 Startup.cs 中)中,您需要此代码来设置 Swagger 文档:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("{SWAGGER_VERSION}", new OpenApiInfo { Title = "{PROJECT_TITLE}", Version = "{SWAGGER_VERSION}" });
});