Mono 和 Nginx:StaticFileHadler 提供的索引 (/) 404

Mono and Nginx: Index (/) 404 served by StaticFileHadler

我已经在 Ubuntu 14.04 上使用 NGINX (1.8.1)[=51] 成功设置了 Mono(稳定版 4.2.3.4) =] 托管 ASP.NET MVC 应用程序,效果很好。我唯一无法解决的是 "index/root (/) 404" 问题。

我正在为 catchall 路由使用自定义 CustomMvcRouteHandler:

routes.MapRoute(
    "UrlHandler", // Route name
    "{*url}",
    null,
    null,
    new[] { "web.Controllers" }
    ).RouteHandler = new CustomMvcRouteHandler();

这很好用,所有预期的请求都通过 CustomMvcRouterHandler() 进行路由; 但不适用于索引 (/)。由于任何原因,索引请求 (/) 正在由 StaticFileHandler 提供服务并抛出此错误:

System.Web.HttpException:找不到资源

描述:您正在查找的 HTTP 404.The 资源(或其依赖项之一)可能已被删除、名称已更改或暂时不可用。请检查以下 URL 并确保拼写正确。

详细信息:请求URL:/

异常堆栈跟踪:

    at System.Web.StaticFileHandler.ProcessRequest (System.Web.HttpContext context) <0x407e59f0 + 0x00753> in <filename unknown>:0 
    at System.Web.DefaultHttpHandler.BeginProcessRequest (System.Web.HttpContext context, System.AsyncCallback callback, System.Object state) <0x407e5720 + 0x00153> in <filename unknown>:0 
    at System.Web.HttpApplication+<Pipeline>c__Iterator1.MoveNext () <0x408c5000 + 0x04485> in <filename unknown>:0 
    at System.Web.HttpApplication.Tick () <0x408c2730 + 0x00057> in <filename unknown>:0 

请注意,它仅适用于 Mono、我的 Windows 开发机器,甚至任何 Windows IIS 托管具有相同 web.config 等即使对于根 (/) 请求也能正常工作,并且这些请求正在通过 CustomMvcRouteHandler() 进行路由。

我真的不明白为什么 Mono 使用 StaticFileHandler 来提供索引 (/)。如果我在 Web 结构的根目录中创建 index.html 文件,那么它由 StaticFileHandler 提供(如预期的那样,因为静态文件处理程序正在寻找该文件)。

这是站点的 NGINX 配置文件:

server {
    listen  80;
    listen [::]:80;
    server_name example.com;
    access_log /var/www/example.com/logs/access.log;
    error_log /var/www/example.com/logs/error.log;

    include /etc/nginx/fastcgi_params;

    location / {
        fastcgi_index /;
        root /var/www/example.com/www/;
        fastcgi_pass 127.0.0.1:9000;
    }
}

我现在使用的解决方法是改变线路:

        fastcgi_index /;

        fastcgi_index /Default.aspx;

这样根访问权限 (/) 将更改为 /Default.aspx 并通过 ASP.NET MVC 管道进行路由,但当然我需要更改代码并处理 /Default.aspx 作为 /.

有什么想法吗?

发布问题后一个小时后想出了解决方案,该死的。

问题在于包罗万象的路由规范和 "defaults" 参数为 NULL。以这种方式更改它解决了问题:

 routes.MapRoute(
     "UrlHandler", // Route name
      url: "{*url}",
      defaults: new { controller = "Home", action = "Index" },
      constraints: null,
      namespaces: new[] { "web.Controllers" }
      ).RouteHandler = new CustomMvcRouteHandler();

查看控制器 = "Home"、操作 = "Index" 的默认值。 ASP.NET MVC 管道甚至为索引 (/) 路由指定默认值。

这样做的副作用是,"controller" 和 "action" 的 RouteData.Values 按照默认值添加到集合中,因此如果您想在代码中添加它们 (像我一样),将抛出异常:

已添加具有相同键的项目。

因此,如果需要,最好检查并删除这些值。

 if (requestContext.RouteData.Values.ContainsKey("controller"))
     requestContext.RouteData.Values.Remove("controller");
 if (requestContext.RouteData.Values.ContainsKey("action"))
     requestContext.RouteData.Values.Remove("action");

P.S.: 这都是关于在 IIS 和 Mono 上托管时的那些小差异:).