Search code examples
asp.net-mvcroutesweb-configrouteconfig

MVC homepage not working, RouteConfig and Global files look OK


I'm working in MVC 5 and have taken over a project. When I log onto the homepage "mydomain.com" it comes up with an error:

"Server Error in '/' Application. The resource cannot be found. Description: HTTP 404. Requested URL:/"

If I type in mydomain.com/home/index it comes up with the home page as it should. I figure this is a RouteConfig.cs problem, but everything looks pretty default to me.

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

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

            routes.MapRoute(
                name: "Glossary2",
                url: "{controller}/{action}/{letter}",
                defaults: new { controller = "Teacher", action = "Glossary2", letter = UrlParameter.Optional }
                );

            /* Will need to finish this later.
             * When the contact us form is submitted, it should redirect to Home/Contact/{state}
             * where {state} can be either 'Success' or 'Error', which will display
             * an alert component in the view based on the provided {state}.
             */
            routes.MapRoute(
                name: "ContactSuccess",
                url: "{controller}/{action}/{submissionStatus}",
                defaults: new { controller = "Home", action = "Contact", submissionStatus = UrlParameter.Optional }
                );

            /* Will need to finish this later.
             * When the contact us form is displayed, it should check to see if a reason for contacting
             * us is already set. If it is, it should automatically select the appropriate reason on the
             * dropdown menu.
             */
            routes.MapRoute(
                name: "ContactReason",
                url: "{controller}/{action}/{reason}",
                defaults: new { controller = "Home", action = "Contact", reason = UrlParameter.Optional }
                );
        }
    }
}

I'm not sure what the CustomeViewEngine is doing and haven't really messed around with it yet. I've also inspected the Global.asax.cs file and it looks pretty standard as well.

namespace Source
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            ViewEngines.Engines.Add(new CustomViewEngine());
        }
    }
    public class CustomViewEngine : RazorViewEngine
    {
        public static readonly string[] CUSTOM_PARTIAL_VIEW_FORMATS = new[]
            { "~/Views/Selection/{0}.cshtml" };
        public CustomViewEngine()
        {
            base.PartialViewLocationFormats = base.PartialViewLocationFormats.Union(CUSTOM_PARTIAL_VIEW_FORMATS).ToArray();
        }
    }
}

Is there a way to trace down why the domain name is not getting routed to home/index? If I put the Default mapping at the bottom of the RouteConfig file it wants to automatically direct to the login page. Again, I'm not really understanding why this would be acting this way.


Solution

  • I think your route definitions are not in right order, the route order evaluates from top to bottom (the most specific path resolved first).

    Hence, the default route should be take place as the last defined route:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        // custom path at the top (or top-most depending on priority)
        routes.MapRoute(
            name: "Example",
            url: "Example/{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    
        // default path at the bottom-most
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
    

    Additionally, all URLs defined in every route in the sample are in same pattern (using {controller}/{action}/{parameter}), hence it potentially conflict between each other. You can use plain strings to differentiate similar route patterns:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        routes.MapRoute(
            name: "Glossary2",
            url: "Teacher/{action}/{letter}",
            defaults: new { controller = "Teacher", action = "Glossary2", letter = UrlParameter.Optional }
        );
    
        routes.MapRoute(
            name: "ContactSuccess",
            url: "{controller}/{action}/SubmissionStatus/{submissionStatus}",
            defaults: new { controller = "Home", action = "Contact", submissionStatus = UrlParameter.Optional }
        );
    
        routes.MapRoute(
            name: "ContactReason",
            url: "{controller}/{action}/Reason/{reason}",
            defaults: new { controller = "Home", action = "Contact", reason = UrlParameter.Optional }
        );
    
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
    

    Note: Use RouteDebugger to find out which routes handled by RouteConfig when accessing specific routes.