1

我一直在搞乱 MVC4 中的 RouteConfig 类,我遇到了一个奇怪的行为,我不知道它为什么会发生。

我在课堂上有以下代码:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add("Favicon", new Route("favicon.ico", new FavIconFileHandler()));

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );


}

这个想法是,当有人访问http://my.domain.com/favicon.ico时,将根据所使用的子域提供不同的文件。例如,http://app1.domain.com会得到与http://app2.domain.com不同的一个。我知道这可以通过 IISRewrite 来完成,但我也在尝试探索这条路线来解决问题。

这里的代码实际上是有效的,问题是现在当我在 MVC 中提交任何表单时,我得到以下 URL:

http://localhost:13424/favicon.ico?action=ShowResult&controller=Home

代替

http://localhost:13424/Home/ShowResult

为什么会发生这种情况以及为什么将 favicon.ico 附加到 URL?

4

2 回答 2

1

您可以使用启用的 RouteDebugging 来调试此行为。

修改 web.config :

<add key="RouteDebugger:Enabled" value="true" /><appSettings>

确保您的默认路由处理程序位于路由表的底部

于 2013-06-27T11:19:55.733 回答
1

您最好将处理程序添加到 web.config handlers 部分,然后在路由映射中忽略它。但是,如果您想使用您的解决方案,您需要创建一个自定义路由类和 ovveride GetVirtualPath 方法,这里是注册路由的示例代码:

 public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add("Favicon", new CustomRoute("favicon.ico", new FavIconFileHandler()));

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );


}

自定义路由类:

 public class CustomRoute : Route
    {
        public CustomRoute(string uri, IRouteHandler handler) : base(uri, handler)
        {
        }

        public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
        {
            return null;
        }
    }

这是因为 ASP.NET MVC 在生成操作链接时将为每个注册的路由调用 VirtualPathData,如果路由返回 null,则不会考虑该路由生成 URL。

这是 MVC 中检查 VirtualPathData 的结果的代码:

public VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
    requestContext = this.GetRequestContext(requestContext);
    using (this.GetReadLock())
    {
        foreach (RouteBase current in this)
        {
            VirtualPathData virtualPath = current.GetVirtualPath(requestContext, values);
            if (virtualPath != null)
            {
                virtualPath.VirtualPath = RouteCollection.GetUrlWithApplicationPath(requestContext, virtualPath.VirtualPath);
                return virtualPath;
            }
        }
    }
    return null;
}
于 2013-06-27T12:58:22.537 回答