Steven Yates
Steven Yates

Reputation: 2480

MVC Attribute Routing

Is it possible to modify the template a route at runtime.

Example:

[Route("Home/Index")]
public View Index()
{
   return View();
}

I have seen the new IDirectRouteProvider can the Template has no setter.

Can i do this somewhere else?

Thanks

Steve

Upvotes: 0

Views: 1036

Answers (2)

AMS
AMS

Reputation: 439

This is how I do it without the CoreEntityDirectRouteProvider class and removing the routes.MapRoute(...) declaration.

[RoutePrefix("Home")]
[Route("{action=Index}")]
public class HomeController : Controller
{
    [Route("Index")]
    public ActionResult Index()
    {
        return View();
    }

Upvotes: 0

Steven Yates
Steven Yates

Reputation: 2480

Nevermind,

This is how i have done it, created my own route provider

public class CoreEntityDirectRouteProvider : DefaultDirectRouteProvider
{
    public CoreEntityDirectRouteProvider()
    {
        CoreEntity = Resource.CORE_ENTITY_NAME;
    }

    public string CoreEntity { get; private set; }

    protected override IReadOnlyList<IDirectRouteFactory> GetActionRouteFactories(ActionDescriptor actionDescriptor)
    {

        IReadOnlyList<IDirectRouteFactory> actionRouteFactories = base.GetActionRouteFactories(actionDescriptor);

        List<IDirectRouteFactory> actionDirectRouteFactories = new List<IDirectRouteFactory>();
        foreach (IDirectRouteFactory routeFactory in actionRouteFactories)
        {
            RouteAttribute routeAttr = routeFactory as RouteAttribute;
            if (routeAttr != null && !string.IsNullOrEmpty(routeAttr.Template))
            {
                string template = routeAttr.Template;

                if (template.Contains("{{CORE_ENTITY}}"))
                {
                    template = template.Replace("{{CORE_ENTITY}}", CoreEntity);
                }
                RouteAttribute routeAttribute = new RouteAttribute(template);
                routeAttribute.Order = routeAttr.Order;
                routeAttribute.Name = routeAttr.Name;
                actionDirectRouteFactories.Add(routeAttribute);
            }
        }

        return actionDirectRouteFactories.ToSafeReadOnlyCollection();
    }
}

Then i use it when calling MapMvcAttributeRoutes in RouteConfig, like this:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes(new CoreEntityDirectRouteProvider());


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

If someone else has a more 'proper' way to achieve this then please share.

Thank you.

Steve

Upvotes: 1

Related Questions