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 上托管时的那些小差异:).
我已经在 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 上托管时的那些小差异:).