Şafak Gür
Şafak Gür

Reputation: 7345

How to omit controller name for Home views

Let's say I have this structure:

Home/
    Index
    About

Project/
    Index
    Details

How can I omit the controller name for Home views?

I want to write {root}/About instead of {root}/Home/About.
I also want {root}/Project/Details/2 to work.

Here is what I tried in RegisterRoutes:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

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

routes.MapRoute(
    name: "HomeRoute",
    url: "{action}",
    defaults: new
    {
        controller = "Home",
        action = "Index"
    }
);

Edit: I also tried swapping the order of my MapRoute calls but it still doesn't work.
What I need is:

{root}/Home/Index         > HomeController.Index
{root}/Home               > HomeController.Index
{root}                    > HomeController.Index
{root}/Home/About         > HomeController.About
{root}/About              > HomeController.About
{root}/Project/Index      > ProjectController.Index
{root}/Project            > ProjectController.Index
{root}/Project/Details/12 > ProjectController.Details

Upvotes: 2

Views: 130

Answers (1)

haim770
haim770

Reputation: 49095

Just change the order of your MapRoute calls:

routes.MapRoute(
    name: "HomeRoute",
    url: "{action}",
    defaults: new { controller = "Home", action = "Index" }
);

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

The 'Default' route has to be defined last, otherwise it matches all Url patterns and no further routes are evaluated.

Update:

As per your edit, since you want to preserve the 'controller-name-only' route as well. Try this:

public class ActionExistsConstraint : IRouteConstraint
{
    private readonly Type _controllerType;

    public ActionExistsConstraint(Type controllerType)
    {
        this._controllerType = controllerType;
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        var actionName = values["action"] as string;

        if (actionName == null || _controllerType == null || _controllerType.GetMethod(actionName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.IgnoreCase) == null)
            return false;

        return true;
    }
}

Then:

routes.MapRoute(
    name: "HomeRoute",
    url: "{action}",
    defaults: new { controller = "Home", action = "Index" },
    constraints: new { exists = new ActionExistsConstraint(typeof(HomeController)) }
);

See MSDN

Upvotes: 6

Related Questions