1
votes

I've just started a new MVC project, and the default route doesn't seem to be working as I expect.

Routing Configuration:

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 }
    );
}

I have an ActionLink going to the "Index" action on the "Scripts" controller with @Html.ActionLink("Scripts", "Index", "Scripts").

public class ScriptsController : Controller
{
    public ActionResult Index()
    {
        var model = new IndexModel();
        .......
        return View(model);
    }
}

When clicking this link, the browser tries to navigate to "http://localhost:1733/Scripts/", and the browser displays a "Directory listing denied" error. When I manually change the URL to "http://localhost:1733/Scripts/Index" it works fine.

Shouldn't the default route automatically infer the "Index" action? It does seem to be working for the ManageController class that was part of the default MVC site template ("http://localhost:1733/Manage" brings up the Index ActionResult of the ManageController)

What am I doing wrong?

1

1 Answers

7
votes

I guess you have a physical "Scripts" in your app root. The error message you see is the expected behavior. When the GET request for /Scripts comes, IIS does not know whether to return the directory content (of Scripts) or have mvc return the ScriptsController result. It is confusing.

You should try not to name your controller same as the physical directory name. Change either of the name.

If you do not want to rename either of those, you can set the RouteExistingFiles property to true to tell the framework whether routing should handle urls that match an existing physical file/directory.

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

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

        routes.RouteExistingFiles = true;
    }
}

You need to make sure that you do not have any action methods in the ScriptsController which matches the physical files/static resources (Ex : bundled/minimized script resource name).