Witcher Witcher - 1 year ago 44
ASP.NET (C#) Question

How to register new route from the controller action method?

I have to develop some pages and public handles (aka, aliases) for those pages.

(To get the idea: in the facebook you can have alias for your page and the final URL will look like

instead of

I store public handle in the db table and make sure that all handles are unique.
Now I've added routing registration for my handles:

public override void RegisterArea(AreaRegistrationContext context)
// Assume, that I already have dictionary of handles and ids for them
foreach(var pair in publicHandlesDictionary)
var encId = SomeHelper.Encrypt(pair.Key);
context.MapRoute(pair.Value, pair.Value,
new {controller = "MyController", action="Index", id = encId});

So, now I can reach some page by using address
instead of
And this stuff works fine, ok.

But what if I start the applicatian, then add new handle? This new handle will not be registered, because all routes registration are performed when app is started. Basically, I have to restart the application (the IIS, the VS/IIS Express, the Azure, doesn't matter) to get all routes be registered again including my new handle.

So, is there any way to add new route registration from the controller's action method (when new handle is added)?

Answer Source

you dont need to create all routes at app start.

just use IRouteConstraint to determine what should follow alias logic

public class AliasConstraint : IRouteConstraint
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        var alias = values[parameterName];
        // Assume, that I already have dictionary of handles and ids for them
        var publicHandlesDictionary = SomeStaticClass.Dic;
        if (publicHandlesDictionary.ContainsValue(alias))
            //adding encId as route parameter
            values["id"] = SomeHelper.Encrypt(publicHandlesDictionary.FirstOrDefault(x => x.Value == alias).Key);
            return true;
        return false;

//for all alias routes
    name: "Alias",
    url: "{*alias}",
    defaults: new {controller = "MyController", action = "Index"},
    constraints: new { alias = new AliasConstraint() }

//for all other default operations
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }

this way you can update publicHandlesDictionary anytime and route will pick up the changes