ASP.Net MVC Routing Issue – Question Mark appears on the links

asp.net-mvc

I have a public website which accepts a pagename, this then defaults to a controller and action with the pagename as the unique identifier to render the correct view. eg. http://www.mydomain.com/homepage

I also have a admin area where all CRUD stuff takes place access via a prefix of admin. eg. http://www.mydomain.com/admin/controller/action

Everything has been fine until I changed something recently and now when I got to http://www.mydomain.com/homepage the links I have such as:

<ul id="menu">              
   <li><%= Html.ActionLink("Home", "Details", "WebPage", new { pageName = "homepage" }, null)%></li>
   <li><%= Html.ActionLink("About", "Details", "WebPage", new { pageName = "homepage" }, null)%></li>                    
</ul>

no longer appear as http://www.mydomain.com/homepage but instead http://www.mydomain.com/Admin/WebPage/Details?pageName=homepage

Can someone help?

Here is my Global.asax:

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

        routes.MapRoute("AdminRoot",
            "Admin",
            new { controller = "Admin", action = "Index" }
            );

        routes.MapRoute(
            "LogOn",                                              // Route name
            "LogOn",                           // URL with parameters
            new { controller = "Account", action = "LogOn" },
            new { action = "LogOn" }
        );

        routes.MapRoute("Account",
          "Account/{action}",
          new { controller = "Account", action = "" }
          );

        //routes.MapRoute(
        //    "Default",                                              // Route name
        //    "{controller}/{action}/{id}",                           // URL with parameters
        //    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        //);


        routes.MapRoute(
        "ErrorRoute",                                              // Route name
        "Error/Error404",                           // URL with parameters
        new { controller = "Error", action = "Error404" }
        );


        routes.MapRoute("Admin",
            "Admin/{controller}/{action}/{id}",
            new { controller = "Admin", action = "Index", id = "" }
            /*,new { action = "Create|Edit|Delete" }*/
            );

        routes.MapRoute("EventNewsData",
           "Admin/{controller}/{action}/{year}/{month}",
           new { controller = "Admin", action = "Index", year = 0, month = 0 }
            /*,new { action = "Create|Edit|Delete" }*/
           );

        routes.MapRoute(
            "Default",                                              // Route name
            "{pageName}/{moreInfoID}",                           // URL with parameters
            new { controller = "WebPage", action = "Details", pageName = "homepage", moreInfoID = 0 },
            new { action = "Details" }
            );


        routes.MapRoute("Error", "{*url}", new { controller = "Error", action = "Error404" });

    }

UPDATE: This has fixed it but not really sure why

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

        routes.MapRoute("AdminRoot",
            "Admin",
            new { controller = "Admin", action = "Index" },
            new { action = "Index" }
            );

        routes.MapRoute(
            "LogOn",                                              // Route name
            "LogOn",                           // URL with parameters
            new { controller = "Account", action = "LogOn" },
            new { action = "LogOn" }
        );

        routes.MapRoute("Account",
          "Account/{action}",
          new { controller = "Account", action = "" }
          );

        //routes.MapRoute(
        //    "Default",                                              // Route name
        //    "{controller}/{action}/{id}",                           // URL with parameters
        //    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        //);





        routes.MapRoute("Admin",
            "Admin/{controller}/{action}/{id}",
            new { controller = "Admin", action = "Index", id = "" }
            , new { action = "Create|Edit|Delete|Index|DeleteFromIndex" }
            );

        routes.MapRoute("EventNewsData",
           "Admin/{controller}/{action}/{year}/{month}",
           new { controller = "Admin", action = "Index", year = 0, month = 0 }
            , new { action = "GetCalendarData" }
           );

        routes.MapRoute(
            "Default",                                              // Route name
            "{pageName}/{moreInfoID}",                           // URL with parameters
            new { controller = "WebPage", action = "Details", pageName = "homepage", moreInfoID = 0 },
            new { action = "Details" }
            );

        routes.MapRoute(
        "ErrorRoute",                                              // Route name
        "Error/Error404",                           // URL with parameters
        new { controller = "Error", action = "Error404" }
        );

        routes.MapRoute("Error", "{*url}", new { controller = "Error", action = "Error404" });

    }

Best Solution

Maybe the problem is in action = "Details" constraint (There is no "{action}" in "{pageName}/{moreInfoID}"):

routes.MapRoute(
        "Default",                                              // Route name
        "{pageName}/{moreInfoID}",                           // URL with parameters
        new { controller = "WebPage", action = "Details", pageName = "homepage", moreInfoID = 0 },
        new { action = "Details" }
        );

UPDATED:

Now your code is using this route:

routes.MapRoute("Admin",
        "Admin/{controller}/{action}/{id}",
        new { controller = "Admin", action = "Index", id = "" }
        /*,new { action = "Create|Edit|Delete" }*/
        );

But you can use Html.RouteLink instead:

<ul id="menu">              
    <li><%= Html.RouteLink("Home", "Default", new { pageName = "homepage" })%> </li>
    <li><%= Html.RouteLink("About", "Default", new { pageName = "homepage" })%> </li>                    
</ul>

UPDATED:

ASP.NET Routing looks for route with "Details" action and "WebPage" controller ("pageName" is optional) and match "Admin" route.

UPDATED:

Or add this route before "Admin" route:

routes.MapRoute("TheRoute",
    "{pageName}/{moreInfoID}",
    new { controller = "WebPage", action = "Details", moreInfoID = 0 },
    new { pageName = "homepage" }
);