I must be dense. After asking several questions on StackOverflow, I am still at a loss when it comes to grasping the new routing engine provided with ASP.NET MVC. I think I\'v
i think your question is similar to mine. ASP.NET MVC Routing
this is what robert harvey answered.
routes.MapRoute( _
"SearchRoute", _
"{id}", _
New With {.controller = "User", .action = "Profile", .id = ""} _
)
Here is an alternative way to standar route registration:
1. Download RiaLibrary.Web.dll and reference it in your ASP.NET MVC website project
2. Decoreate controller methods with the [Url] Attributes:
public SiteController : Controller
{
[Url("")]
public ActionResult Home()
{
return View();
}
[Url("about")]
public ActionResult AboutUs()
{
return View();
}
[Url("store/{?category}")]
public ActionResult Products(string category = null)
{
return View();
}
}
BTW, '?' sign in '{?category}' parameter means that it's optional. You won't need to specify this explicitly in route defaults, which is equals to this:
routes.MapRoute("Store", "store/{category}",
new { controller = "Store", action = "Home", category = UrlParameter.Optional });
3. Update Global.asax.cs file
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoutes(); // This do the trick
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
How to set defaults and constraints? Example:
public SiteController : Controller
{
[Url("admin/articles/edit/{id}", Constraints = @"id=\d+")]
public ActionResult ArticlesEdit(int id)
{
return View();
}
[Url("articles/{category}/{date}_{title}", Constraints =
"date=(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])")]
public ActionResult Article(string category, DateTime date, string title)
{
return View();
}
}
How to set ordering? Example:
[Url("forums/{?category}", Order = 2)]
public ActionResult Threads(string category)
{
return View();
}
[Url("forums/new", Order = 1)]
public ActionResult NewThread()
{
return View();
}
The important thing to understand is that the routes are matched in the order they are registered. So you would need to register the most specific route first, and the most general last, or all requests matching the general route would never reach the more specific route.
For your problem i would register routing rules for each of the special pages, like "register" and "login" before the username rule.
You could handle that in the home controller, but the controller method would not be very elegant. I'm guessing something like this might work (not tested):
routes.MapRoute(
"Root",
"{controller}/{view}",
new { controller = "Home", action = "Index", view = "" }
);
Then in your HomeController:
public ActionResult Index(string view) {
switch (view) {
case "":
return View();
case "register":
return View("Register");
default:
// load user profile view
}
}
What about
routes.MapRoute(
"Profiles",
"{userName}",
new { controller = "Profiles", action = "ShowUser" }
);
and then, in ProfilesController, there would be a function
public ActionResult ShowUser(string userName)
{
...
In the function, if no user with the specified userName is found, you should redirect to the default {controller}/{action}/{id} (here, it would be just {controller}) route.
Urls like www.twitter.com/login should be registered before that one.
routes.MapRoute(
"Login",
"Login",
new { controller = "Security", action = "Login" }
);
OK I haven't ever properly tried this, but have you tried to extend the RouteBase class for dealing with users. The docs for RouteBase suggest that the method GetRouteData should return null if it doesn't match the current request. You could use this to check that the request matches one of the usernames you have.
You can add a RouteBase subclass using:
routes.Add(new UserRouteBase());
When you register the routes.
Might be worth investigating.