Reputation: 1220
We've got an area on our site where people can sign up and be given their own page on the site which we want to host at ~/pageSlug. I've tried doing it with a rule in Global.asax, but that broke the fundamental default route that allows ~/Controller to map directly to the Index action. I'm not being allowed to put any kind of separator in front of the userSlug, so ~/p/pageSlug isn't really an option here.
In terms of getting the user pages added to the routes, I'm cycling through the pages at App_Start and explicitly adding them to the RoutesTable. This is working fine, and we've got AppPool refreshes set long enough to make this a once a day task. This does leave us with a 24-hour turnaround to "get pages live" for our users though, which I'm trying to solve.
Ideally, what I'd like to do is add the relevant route to the RouteTable dynamically once a user has signed up. I've tried doing that with:
RouteTable.Routes.Add(
RouteTable.Routes.MapRoute(
toAdd.UrlSlug + "Homepage",
toAdd.UrlSlug,
new { controller = "Controller", View = "View", urlSlug = toAdd.UrlSlug }
)
);
but that didn't seem to work. I can't find a solution anywhere else, and I'm sure my code is both horribly naive and betrays a lack of understanding of routing - please help!
Upvotes: 5
Views: 7922
Reputation: 787
I recently just realized it too, instead of adding routes dynamically which I am not sure can be done so without using external libraries such as Route Magic . I am confident that if you design your architecture right, Routing Constraint is all you might just need. Since my application is small, I am using only one implemented controller and dynamically creating the rest (experimental at the moment but it should work).
Consider following routes
routes.MapRoute(
name: "ContactRequests_Operations",
url: "ContactRequests-{operation}",
defaults: new { controller = "Content", action = "Module_Direct", id = "ContactRequests" , operation = "Get" }
);
routes.MapRoute(
name: "Messages",
url: "Messages",
defaults: new { controller = "Content", action = "Direct", id ="Messages" }
);
Upvotes: 2
Reputation: 641
What if you try this, using route constraint. Get out list of all users and constraint the chosen route to match entries in that list
public class UserPageConstraint : IRouteConstraint
{
public static IList<string> UserPageNames = (Container.ResolveShared<IUserService>()).GetUserPageNames();
bool _IsUserPage;
public UserPageConstraint(bool IsUserPage)
{
_IsUserPage = IsUserPage;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (_IsUserPage)
return UserPageNames.Contains(values[parameterName].ToString().ToLower());
else
return !UserPageNames.Contains(values[parameterName].ToString().ToLower());
}
}
Then in the Global.asax.cs, set up a route for users as follows:
routes.MapRoute("UserHome", "{userPage}", new { controller = "UserPageController", action = "Index" }, new { userPage = new UserPageConstraint(true) });
For this above route, in the action 'index' of the UserPageController, we will have the userPage as the parameter.
For other routes relative to the userPage Home, we can add routes accordingly. for example, the userdetails page route can be added as follows:
routes.MapRoute("UserHome", "{userPage}/mydetails", new { controller = "UserPageController", action = "Details" }, new { userPage = new UserPageConstraint(true) });
You can try this and see.
Upvotes: 5
Reputation: 46008
I don't think you can add route dynamically.
Take a look at this question, maybe it will help you: ASP.NET MVC custom routing for search
Upvotes: 0