在IIS 10上出现ASP.NET Core 404错误

42

我在 IIS 10 上运行 ASP.NET Core web 应用程序时遇到问题。我正在使用 AngularJS 开发单页应用程序。

index.html 可以正常加载,但是后端请求在 IIS 10 上失败,并显示 404 错误代码。在使用 IIS Express 的 Visual Studio 中,它可以完美运行。

有没有人知道如何修复后端请求的问题?

以下是我的 Program.cs:

public static void Main(string[] args)
{
    var host = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .Build();

    host.Run();
}

这是我在Startup.cs中的Configure方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseDefaultFiles();

    app.UseStaticFiles();

    app.UseIdentity();

    // Custom middleware for Angular UI-Router
    app.Use(async (context, next) =>
    {
        if (!Path.HasExtension(context.Request.Path.Value)
        && context.Request.HttpContext.Request.Headers["X-Requested-With"] != "XMLHttpRequest"
        && context.Request.Method.ToUpper() != "POST"
        && context.Request.Method.ToUpper() != "PUT"
        && context.Request.Method.ToUpper() != "DELETE")
        {
            await context.Response.WriteAsync(File.ReadAllText(env.WebRootPath + "/index.html"));
        }

        await next();
    });

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "api/{controller=Home}/{action=Index}/{id?}");
    });
}

启用 ASP.NET Core 日志记录(可能使用 Debug 日志级别),查看是否有任何消息说明为什么此操作失败。 - Kiran
请发布您的 web.config 文件。 - Shaun Luttin
你配置了MVC服务吗? - Shaun Luttin
你是否添加了一个带有Index操作的Home控制器? - Shaun Luttin
13个回答

33

在我的情况下,问题是我的控制器抛出了异常,因此框架尝试使用不存在的异常处理程序页面,因此出现了404错误,控制器本身抛出了500错误。


9
你是如何进行故障排除的? - Hristo Alexsiev
2
是的,我也很想知道。在开发模式下,异常应该显示在页面上,但它没有。不确定是否有异常导致我的404错误。 - Mocas
2
我认为由于某种原因路由出现了问题,如果我包括完整路径,我可以访问该页面,这个可以工作-> https://localhost:5001/home/index。这个不行-> https://localhost:5001/home,也不行https://localhost:5001/。 - Mocas
在你的控制器中添加try catch语句以检查此答案。 - Akbar Asghari

32

为了方便搜索。

当我在使用IIS时出现404错误。我按照正确的发布程序步骤(这里)和详细部署步骤(这里)进行操作。

经过一番探索,我最终在Rick Strahl博客文章中找到答案。

基本上,在创建应用程序池时,除了将其设置为“无托管代码”之外,我还需要进入高级设置并将应用程序池标识设置为“Network Service”。在我的机器上,ApplicationPoolIdentity是可以接受的,但是在我部署到的机器上不行。

输入图像描述

因此,为了清晰明了,我的完整步骤是:

创建软件包:

  1. 创建dotnet core网站(我使用的是Visual Studio 2017)
  2. 发布。可以使用VS的发布功能,但我使用了CLR通过包管理器发布。命令如下:

    dotnet publish -c Release -r win-x64 --self-contained

我必须使用 win-x64 标识符,因为我们需要与64位Windows Server 2008兼容。

部署步骤:

  1. 在C:\ inetpub \ wwwroot中创建一个文件夹(例如“ testsite”)
  2. 将发布文件夹({root} \bin\Release\netcoreapp2.1\win-x64\publish)的内容复制到新的“testsite”文件夹中(或您的等效文件夹)。
  3. 在主机计算机上安装dotnet core 运行时(而不是SDK!)
  4. 打开IIS,右键单击“应用程序池”,然后选择“添加应用程序池”。创建一个.NET CLR版本设置为“无托管代码”的应用程序池。
  5. (我的计算机不需要这一步,但服务器需要)再次点击“应用程序池”。右键单击您的新应用程序池并选择“高级设置”。将标识更改为“Network Service”(如上图所示)。
  6. 回到IIS的顶层,展开“默认网站”,右键单击您的网站文件夹并选择“转换为应用程序”。选择无托管代码的新应用程序池。
  7. 以管理员身份打开命令提示符并运行 iisreset 。您应该只需要在安装dotnet core运行时后第一次使用此选项。
  8. 访问网站(例如 http://localhost/testsite

1
根据MSDN文档,当它是“自包含的”时,您不需要安装运行时:https://learn.microsoft.com/en-us/dotnet/core/deploying/ - Aage
2
@Aage - 这是一个很好的观点 - 对于自包含应用程序,您不需要它。当然,您仍然需要 .NET Core IIS 托管捆绑包。 - JsAndDotNet

24

你的代码在我的机器上使用Kestrel可正常工作。一个好的故障排除步骤是找出问题是出在你的ASP.NET Core应用程序还是你的IIS托管配置中。

请尝试从你的项目根目录开始执行这个操作。

dotnet restore
dotnet run
你将会看到类似于这样的东西:
Hosting environment: Production
Content root path: C:\MyApplicationPath
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

在您的浏览器中打开以下两个URL。如果它们无法正常工作,则表示您的应用程序存在问题。如果它们可以正常工作,则表示您的IIS托管存在问题。

localhost:5000        // you will see your index.html page
localhost:5000/api    // you will see your default routes output

3
谢谢,我已经解决了。问题出在我的应用程序上,但如果应用程序出现问题就抛出404错误,这有点奇怪。 - Mate Zabo
1
应用程序出了什么问题?你的修复过程包括什么? - Shaun Luttin
1
问题是缺少配置文件。我有3个环境的appsettings文件,分别为开发、暂存和生产环境,并包含必要的连接字符串。默认发布选项仅包含appsettings.json。因此,我需要将值更改为appsettings*.json以复制所有环境设置。 - Mate Zabo
非常有用。我的API实际上是通过IIS和在服务器上运行EXE工作的。看起来是我的Swagger页面给我返回了404错误。 - Christopher Painter
提到 Swagger 给了我一个想法,我的 http://example.com/mysitepoolname 访问时显示 404 错误,结果我只需要访问正确的 URL http://example.com/swagger/index.html,问题就解决了。希望能够帮助有同样问题的人节省寻找解决方案的时间。 - mirageservo

7

在我的情况下,问题通过在web.config中设置环境变量得到解决。

<aspNetCore processPath="dotnet"
      arguments=".\MyApp.dll"
      stdoutLogEnabled="false"
      stdoutLogFile=".\logs\stdout"
      hostingModel="inprocess">
  <environmentVariables>
    <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
     </environmentVariables>
</aspNetCore>

5

2

对于任何遇到相同问题的人,可能不是你部署的问题。如果你正在部署默认的示例Web API项目(WeatherForecastAPI),然后收到404错误,那是因为Swagger在生产或发布模式下未启用。所以没有控制器方法来处理接收发送到根URL的请求。

但是,如果直接调用端点(在这种情况下是{your_app_url}/WeatherForecast),则可以正常工作。


1

另一个非常愚蠢但很有可能的变体是,由于错误的部署设置,应用程序部署在与您预期不同的文件夹中(例如:您的服务器根目录而不是子文件夹)。


1

1

我使用了.AddRazorPageOptions(rpo => rpo.RootDirectory = "/Folder")配置了一个根目录,但是我忘记了,我的.cshtml文件仍然在项目的根目录中。我只需要创建/Folder文件夹并将我的文件放在那里,就可以解决问题了。


1
如果您正在使用 API 调用,请确保您的类具备以下内容:
[Route("api/[controller]")]
    [ApiController]

在类实例化的上面。

还要确保你有:

[HttpGet()]

例如,在您尝试调试的 API 方法之上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接