MVC routing restriction on controller names

I have routes configured as:

        context.MapRoute(
        name: "Area",
        url: "Area/{controller}/{action}",
        defaults: new
        {
            controller = "Home",
            action = "Dashboard"
        }
        );

        context.MapRoute(
        name: "AccountArea",
        url: "Area/{accountFriendlyId}/{controller}/{action}",
        defaults: new
        {
            controller = "Home",
            action = "Dashboard",
            accountFriendlyId = RouteParameter.Optional
        }
        );

        context.MapRoute(
        name: "AccountCampaignArea",
        url: "Area/{accountFriendlyId}/{campaignFriendlyId}/{controller}/{action}",
        defaults: new
                {
                    controller = "Home", 
                    action = "Dashboard",
                    accountFriendlyId = RouteParameter.Optional,
                    campaignFriendlyId = RouteParameter.Optional
                }
        );

And I have a burning desire to Area/friendlyAccountName/Homelead me to Dashboard(), but it will not work (404). I think the reason is that we are looking for a controller friendlyAccountName.

It’s convenient with the understanding that if I have to choose an account name after one of my controllers, everything falls apart, is there a way to skip to the next route if the line cannot find the corresponding controller? Is there a way to use reflection and avoid constraint support every time I change the list of my controllers?

EDIT

, , , ? , , ( ). , , .

+5
3

? {accountFriendlyId} , .

, AccountArea, , , {accountFriendlyId} , .

, , , , .

UPDATE

{accountFriendlyId} , :

  • {accountFriendlyId} , . URL- .
  • . . - :

context.MapRoute(

    name: "Area",
    url: "Area/{controller}/{action}",
    defaults: new
    {
        controller = "Home",
        action = "Dashboard",
        new { controller = @"(Account|Profile|Maintenance)" }
    }

);

+6

, , ( , ), :

public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
        name: "AccountCampaignArea",
        url: "Area/{accountFriendlyId}/{campaignFriendlyId}/{controller}/{action}",
        defaults: new
            {
                controller = "Home",
                action = "Dashboard",
                accountFriendlyId = RouteParameter.Optional,
                campaignFriendlyId = RouteParameter.Optional,
                id = UrlParameter.Optional
            },
        constraints: new { accountFriendlyId = new ControllerNameConstraint(), campaignFriendlyId = new ControllerNameConstraint() }
        );

        context.MapRoute(
            name: "AccountArea",
            url: "Area/{accountFriendlyId}/{controller}/{action}",
            defaults: new
                {
                    controller = "Home",
                    action = "Dashboard",
                    accountFriendlyId = RouteParameter.Optional,
                    id = UrlParameter.Optional
                },
            constraints: new { accountFriendlyId = new ControllerNameConstraint() }
            );

        context.MapRoute(
        name: "Area",
        url: "Area/{controller}/{action}",
        defaults: new
            {
                controller = "Home",
                action = "Dashboard"
            }
        );
    }

( NotControllerNameContraint):

public class ControllerNameConstraint : IRouteConstraint
{
    private static List<Type> GetSubClasses<T>()
    {
        return Assembly.GetCallingAssembly().GetTypes().Where(
            type => type.IsSubclassOf(typeof(T))).ToList();
    }

    public List<string> GetControllerNames()
    {
        List<string> controllerNames = new List<string>();
        GetSubClasses<Controller>().ForEach(
            type => controllerNames.Add(type.Name));
        return controllerNames;
    }
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (values.ContainsKey(parameterName))
        {
            string stringValue = values[parameterName] as string;
            return !GetControllerNames().Contains(stringValue + "Controller");
        }

        return true;
    }
}

: fooobar.com/questions/167007/...

+6

URL. accountFriendlyId, campaignFriendlyId ? , URL-, , . :

context.MapRoute(null, "Area/{controller}/{action}",
   new { controller = "Home", action = "Dashboard" },
   new { controller = "Foo|Bar" });

context.MapRoute(null, "Area/{accountFriendlyId}/{controller}/{action}",
   new { controller = "Home", action = "Dashboard" },
   new { controller = "Foo|Bar" });

context.MapRoute(null, "Area/{accountFriendlyId}/{campaignFriendlyId}/{controller}/{action}",
   new { controller = "Home", action = "Dashboard" });

, , , , , , UrlRoutingModule, .

+2

All Articles