Is there a supported/known way to uses dashes in a Controller?

May 22, 2012 at 3:53 PM

There are some tricks to do this when defining routes using routes.MapRoute(), but is there a way to allow hyphenated controller names using MvcCodeRouting?

In other words, I have a controller name "MyController" which then has an action like "MyAction."

I'm able to decorate the action with a CustomRoute attribute so I can get:

/MyController/My-Action

...but I'd like:

/My-Controller/My-Action

Coordinator
May 22, 2012 at 4:18 PM

There is no support for aliased controller names, because ASP.NET MVC doesn't support it. DefaultControllerFactory requires that the controller value matches the controller class name (suffixed with "Controller"). Action names can be customized with the [ActionName] attribute.

As you already know, you can use the RouteFormatter setting to hyphenate both controller and action segments, but this doesn't change the actual controller and action names.

Can you tell me more about what you are trying to acomplish?

May 22, 2012 at 4:53 PM

The idea is here:

http://blog.bdcsoft.com/developer-blog/2011/hyphenated-urls-in-asp-net-mvc-3-or-how-my-doggie-got-pwned-by-the-kitty/

Where this "HyphenatedRouteHandler" is essentially re-writing the dashed Controller to a non-dashed version.

When using MapCodeRoutes(), there just isn't a place to use that exact construct, thus my question.

I think RouteFormatter is where I need to be looking but let me know if you have any other thoughts based on the above.

Coordinator
May 22, 2012 at 4:58 PM

RouteFormatter is exactly what you need, give it a try.

May 22, 2012 at 5:19 PM

Great - so what I'm doing is this:

routes.MapCodeRoutes(
	rootController: typeof(Controllers.HomeController),
	settings: new CodeRoutingSettings
	{
		UseImplicitIdToken = true,
		RouteFormatter = args =>
		{
			if (args.SegmentType == RouteSegmentType.Controller && args.OriginalSegment.Contains("-"))
			{
				return args.OriginalSegment.Replace("-", String.Empty);
			}
			return args.OriginalSegment;
		}
	}
);

Basically, if the Controller segment has a dash in it, just remove it. So then if I use a route like this:

 

/My-Controller/Action

...then it should be as if I used:

/MyController/Action

Right? That doesn't seem to work for me.

Coordinator
May 22, 2012 at 5:27 PM
Edited May 22, 2012 at 5:30 PM

You are doing it the other way around. Use RouteFormatter to change the original controller name, e.g. MyController, to something else, e.g. My-Controller. MvcCodeRouting then takes care of mapping My-Controller back to MyController at runtime.

Try this

   routes.MapCodeRoutes(
      rootController: typeof(Controllers.HomeController),
      settings: new CodeRoutingSettings {
         RouteFormatter = args => {
            if (args.SegmentType == RouteSegmentType.Controller)
               return Regex.Replace(args.OriginalSegment, @"([a-z])([A-Z])", "$1-$2");
            return args.OriginalSegment;
         }
      }
   );
Marked as answer by maxtoroq on 10/15/2013 at 10:05 AM
May 22, 2012 at 5:31 PM

I thought that might be it! I was wondering how it would be able to generate the routes given the direction I was going.

Thank you - this works perfectly.

May 22, 2012 at 5:45 PM

I also completely missed that this is the exact example from the Route Formatting docs page. DUH.

Coordinator
May 22, 2012 at 6:26 PM

:-)