Setting up Index as the default route for a controller

22,230

Solution 1

You don't need to lose the default route. The key to avoiding your routes interfere with each other is to order them so the more specific rules precede the less specific ones. For example:

// Your specialized route
routes.MapRoute(
    "Page",
    "Page/{slug}",
    new { controller = "Page", action = "Index" }
);

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

Then your PageController would look like this:

using System.Web.Mvc;

public class PageController : Controller
{
    public string Index(string slug)
    {
        // find page by slug
    }
}

That said, I would strongly advice you to do this instead:

// Your specialized route
routes.MapRoute(
    "Page",
    "Page/{id}/{slug}",
    new { controller = "Page", action = "Index", slug = UrlParameter.Optional }
);

// MVC's default route (fallback)
routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

And your PageController:

using System.Web.Mvc;

public class PageController : Controller
{
    public string Index(int id)
    {
        // find page by ID
    }
}

By including the page ID either at the beginning of your URL (like StackOverflow does) or at the end, you can then just ignore the slug, and instead retrieve your pages by ID. This will save you a ton of headaches if your users change the page name. I have gone through this and it's painful; you basically have to keep a record of all names your pages have had in the past, just so your visitors/search engines don't get a 404 every time a page is renamed.

Hope this helps.

Solution 2

If you don't need a default route that came with project template you can set up one like this:

routes.MapRoute(
    "ControllerDefault",
    "{controller}/{pagename}",
    new { controller = "Page", action = "Index" }
);

And than in your controller you would have an action:

        public ActionResult Index(string pagename)
        {
            //do something
        }
Share:
22,230
MordechayS
Author by

MordechayS

London based .NET developer working at JustEat, keen long distance runner. In my spare time I focus on .NET Core, Docker. Docker for ASP.NET Core (Packt video) Github profile Roadkill .NET Wiki C# Encrypted notes service

Updated on March 10, 2020

Comments

  • MordechayS
    MordechayS about 4 years

    I have a url

    which I want to turn into

    That could also be something like http://www.roadkillwiki.org/Page/my-url-with-spaces - the parameter is a string. The route setup I've tried is:

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

    However this is interfering with the default "id" route that MVC projects come with. Is there any way of achieving this?

  • MordechayS
    MordechayS about 13 years
    My problem is the ID is a guid, which isn't particularly beautiful. So: http://www.roadkillwiki.org/Page/12312-4133-434a23-4424fd-44‌​4/documentation. Looks like I'll need another column with a decent ID
  • Daniel Liuzzi
    Daniel Liuzzi about 13 years
    There are some ways of making GUIDs prettier/SEO-friendlier for example this that shrinks c9a646d3-9c61-4cb7-bfcd-ee2522c8f633 down to 00amyWGct0y_ze4lIsj2Mw but I agree; an int here is probably the least intrusive way.
  • MordechayS
    MordechayS about 13 years
    thanks for the info + links they're very helpful. I think I'm going to stick to numbers as the url is a lot neater