【问题标题】:Getting 404.0 error for ASP.NET MVC 3 app on IIS 7.0 / Windows Server 2008IIS 7.0 / Windows Server 2008 上的 ASP.NET MVC 3 应用程序出现 404.0 错误
【发布时间】:2011-07-03 22:09:32
【问题描述】:

我正在尝试将 ASP.NET MVC 3 应用程序部署到 Windows 2008 x64 服务器(显然运行 IIS 7.0),而 IIS 似乎不想正确地提供内容。所有请求都导致 404.0 错误,因为请求与任何处理程序都不匹配,并且 IIS 正在尝试使用 StaticFile 处理程序来提供请求。该问题似乎与 .NET 4.0 有关,因为我有一个 MVC 2 应用程序在为 .NET 2.0 运行时配置的应用程序池中运行良好。

在 Windows 7 和 Windows Server 2008 R2 上将相同的应用程序部署到 IIS 7.5 服务器时我没有遇到任何问题。

在部署之前,2008 服务器没有安装 .NET 4.0 或 ASP.NET MVC 3,所以这是我在部署应用程序之前采取的步骤:

  1. 已安装 .NET 4.0
  2. 运行 aspnet_regiis.exe(来自 Framework64/v4.0.30319 文件夹)
  3. 使用 Web 平台安装程序安装了 ASP.NET MVC 3
  4. 应用了 MS 更新 KB980368 以使某些 IIS 7.0 或 IIS 7.5 处理程序能够处理 URL 不以句点结尾的请求

对应用程序中的静态资源(JavaScript 文件、图像等)的请求顺利通过,但对 MVC 操作的任何请求都会失败并出现 404.0 错误。我注意到 IIS 正在使用 StaticFile 处理程序来处理这些请求,这显然是不正确的。据我所知,ASP.NET 4.0 处理程序(即 ExtensionlessUrl-ISAPI-4.0* 处理程序)已正确定义,因此我不知道为什么/如何处理这些处理程序之一的请求,并且会落在所有一直到 StaticFile 处理程序。

我还遇到了以下MS knowledge base article,其中提到您应该确保在遇到 404 错误的服务器上启用/安装了 HTTP 重定向和静态内容压缩。我检查了一下,我的服务器已经启用了这两个功能。我什至尝试删除并重新安装这些功能都无济于事。

在这一点上,我完全不知道为什么它不能正常工作。我已经能够在 2 个不同的 IIS 7.0 服务器上复制该问题。我错过了什么?

【问题讨论】:

  • 首先:看看事件查看器,你可以节省时间找到合适的解决方案。
  • @Dario:在任何 Windows 日志中都没有与此问题相关的注意事项。工作进程没有抛出任何异常,并且在 4.0 运行时之上正常运行。 ASP.NET 也不会抛出任何异常,因为它永远不会被 IIS 调用,因为 IIS 正在尝试使用 StaticFile 处理程序来处理请求。
  • 作为记录,我所需要的只是应用修补程序(第 4 条)。

标签: iis-7 .net-4.0 asp.net-mvc-3 windows-server-2008 asp.net-4.0


【解决方案1】:

您实际上只是提醒我,我需要在此处的环境中解决此问题。如果您的情况与我的情况相同,那么这是一个简单的解决方法。

只需将以下内容添加到您的网络配置中:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />

编辑:为手头的问题提供进一步的解释。就我而言,发生的事情是当我添加自定义路由映射时,IIS 将请求视为文件夹/静态文件请求,因此跳过了 ASP.NET 工作进程。这通常在开发环境下表现不同,因为它在开发 Web 服务器下运行,该服务器还将通过 .net 进程传递所有请求。

此 Web Config 条目告诉 IIS,即使 IIS 确定它是静态文件或文件夹,您也应该在每个 Web 请求上运行模块。

【讨论】:

  • 顺便说一句,如果您的 web 服务与您的 aspx 文件位于同一个 web 容器中,您将遇到障碍,因为本机模块将不会运行并且静态文件(如图像)将无法正确提供.将网络服务放在其他地方可能会(希望能减轻)。
  • 从 win7 上的开发环境转到 win2k8 实时服务器时遇到了同样的问题。项目将 webforms 与 mvc3 混合在一起。解决了我的问题。
  • 我在这个问题上花了一个小时才找到这个答案,它奏效了!我们为什么需要这个?如果我们这样做,为什么默认情况下它不存在?
  • 我对我的原始答案添加了更新,并进一步解释了为什么需要它。为什么不包含它是因为 IIS 中的正常行为是不通过工作进程运行静态文件。
【解决方案2】:

问题最终是我的代码完全依赖于仅在 IIS 7.5 中可用的自动启动功能。我能够在 IIS 中的失败请求跟踪功能的帮助下发现问题,现在我已经修改了我的 global.asax.cs 文件,以便应用程序能够正确初始化,无论它是如何/何时加载的。

【讨论】:

  • 你是如何在 global.asax 中初始化它的?
  • 在我的 global.asax.cs 文件 (MvcApplication) 中定义的类实现 IProcessHostPreloadClient 以利用 IIS 7.5 自动启动功能。因此,我将Application_Start 中的所有代码移至Preload 方法。为了支持不使用自动启动功能的情况,我从ApplicationStart 调用Preload。为了确保 Preload 只被调用一次,我使用了一个静态布尔字段,检查该字段以确定 Preload 方法之前是否已执行。
【解决方案3】:

【讨论】:

  • 我应该在原帖中提到应用程序池正在使用集成管道。我没有提到这一点,但事实确实如此。请参阅我的回答,了解我的问题的实际原因和解决方案。
【解决方案4】:

如果您在 IIS 7.5 或更高版本上运行 Web 应用程序,请确保正确启用 IIS 的角色服务。感兴趣的角色服务有:ASP.NET、基本身份验证、HTTP 重定向、ISAPI 过滤器等。

您可以通过添加或删除程序来访问角色服务 - 打开或关闭 Windows 功能。 希望这会有所帮助。

问候, 基兰班达

【讨论】:

    【解决方案5】:

    我的解决方案,在尝试了一切之后:

    糟糕的部署,一个旧的 PrecompiledApp.config 挂在我的部署位置,导致一切都无法正常工作。

    我的最终设置有效:

    • IIS 7.5,Win2k8r2 x64,
    • 集成模式应用程序池
    • web.config 中没有任何变化 - 这意味着没有用于路由的特殊处理程序。这是我对许多其他帖子参考的部分的快照。我正在使用 FluorineFX,所以我确实添加了该处理程序,但我不需要任何其他处理程序:

      <system.web>
        <compilation debug="true" targetFramework="4.0" />
        <authentication mode="None"/>
      
        <pages validateRequest="false" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
        <httpRuntime requestPathInvalidCharacters=""/>
      
        <httpModules>
          <add name="FluorineGateway" type="FluorineFx.FluorineGateway, FluorineFx"/>
        </httpModules>
      </system.web>
        <system.webServer>
          <!-- Modules for IIS 7.0 Integrated mode -->
          <modules>
            <add name="FluorineGateway" type="FluorineFx.FluorineGateway, FluorineFx" />
          </modules>
      
          <!-- Disable detection of IIS 6.0 / Classic mode ASP.NET configuration -->
          <validation validateIntegratedModeConfiguration="false" />
        </system.webServer>
      
    • Global.ashx:(任何注释的唯一方法)

      void Application_Start(object sender, EventArgs e) {
          // Register routes...
          System.Web.Routing.Route echoRoute = new System.Web.Routing.Route(
                "{*message}",
              //the default value for the message
                new System.Web.Routing.RouteValueDictionary() { { "message", "" } },
              //any regular expression restrictions (i.e. @"[^\d].{4,}" means "does not start with number, at least 4 chars
                new System.Web.Routing.RouteValueDictionary() { { "message", @"[^\d].{4,}" } },
                new TestRoute.Handlers.PassthroughRouteHandler()
             );
      
          System.Web.Routing.RouteTable.Routes.Add(echoRoute);
      }
      
    • PassthroughRouteHandler.cs - 这实现了从 http://andrew.arace.info/stackoverflowhttp://andrew.arace.info/#stackoverflow 的自动转换,然后由 default.aspx 处理:

      public class PassthroughRouteHandler : IRouteHandler {
      
          public IHttpHandler GetHttpHandler(RequestContext requestContext) {
              HttpContext.Current.Items["IncomingMessage"] = requestContext.RouteData.Values["message"];
              requestContext.HttpContext.Response.Redirect("#" + HttpContext.Current.Items["IncomingMessage"], true);
              return null;
          }
      }
      

    【讨论】:

    • TestRoute 定义在哪里,我尝试这个时它没有编译,因为它丢失了。
    • @EricBrown-Cal,TestRoute.Handlers 是我的“PassthroughRouteHandler”所在的命名空间的名称。您的命名空间可能很容易成为不同的命名空间。我建议只输入“PassthroughRouteHandler”并让智能感知帮助您正确地“使用...”语句
    【解决方案6】:

    我遇到了同样的问题。我的最终在应用程序启动时组装失败。我启用了 Fusion Log Viewer 以查看哪些程序集失败并找出了答案。我永远不会发现这个,因为它看起来像是一个 MVC 路由问题,但我想我会发布这个,以防其他人也在这个问题上浪费时间!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      • 1970-01-01
      • 2016-01-17
      • 2011-09-27
      • 2014-12-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多