I'm trying to use a base controller with the [InheritedRoute]
attribute. The base class and controllers are created like this:
[InheritedRoute("app/{controller}/{action=index}/{id?}")]
public abstract class MyBaseController : Controller
{
public ActionResult Index()
{
return View();
}
}
public class DefaultController : MyBaseController { }
public class KyleController : MyBaseController { }
[RoutePrefix("app/support")]
[Route("{action=Index}/{id?}")]
public class SupportController : Controller
{
public ActionResult Index()
{
return View();
}
}
The InheritedRouteAttribute
class and stuff:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class InheritedRouteAttribute : Attribute, IDirectRouteFactory
{
public string Name { get; set; }
public int Order { get; set; }
public string Template { get; }
public InheritedRouteAttribute(string template)
{
this.Template = template;
}
public RouteEntry CreateRoute(DirectRouteFactoryContext context)
{
var controllerDescriptor = context.Actions.First().ControllerDescriptor;
var controllerName = controllerDescriptor.ControllerName;
string template;
if (string.Equals(controllerName, "Default", StringComparison.OrdinalIgnoreCase))
{
template = this.Template.Replace("{controller}/", string.Empty);
}
else
{
template = this.Template.Replace("{controller}", controllerName);
}
IDirectRouteBuilder builder = context.CreateBuilder(template);
builder.Name = this.Name ?? controllerName + "_Route";
builder.Order = this.Order;
return builder.Build();
}
}
public class InheritedDirectRouteProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList<IDirectRouteFactory> GetControllerRouteFactories(ControllerDescriptor controllerDescriptor)
{
return controllerDescriptor.GetCustomAttributes(typeof(IDirectRouteFactory), true).Cast<IDirectRouteFactory>().ToArray();
}
}
In my RouteConfig.cs, I'm not using conventional routes:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes(new InheritedDirectRouteProvider());
}
In essence, I want to make it so that if the user is in a DefaultController
, the word "Default" is stripped out of the URL; otherwise, use the standard convention, prepended with "app". If I strip out Default (by taking out {controller}/), then I get the Multiple controller types error whenever I go to another URL. However, if I leave it, everything is fine, except the URL isn't as I wish.
I'm looking at RouteDebugger and seeing what is registered as my routes, and I see (as I expect):
- app/Kyle/{action}/{id}
- app/support/{action}/{id}
- app/{action}/{id}
What am I missing? Why does it think I have a duplicate route, specifically on SupportController
and DefaultController
?