views:

628

answers:

3

I noticed that in MVC 2 Preview 2, AreaRegistration is loading the routes for each area in an arbitrary order. Is there a good way to get one before the other?

For example, I have two areas - "Site" and "Admin". Both have a "Blog" controller.

I would like the following:

/admin/ --> go to Admin's Blog controller
/       --> go to Site's Blog controller.

The problem is that it is loading the site's route first, so it is matching {controller}/{action}/{id} instead of admin/{controller}/{action}/{id} when I go to the url "/admin/". I then get a 404, because there is no Admin controller in the "Site" area.

Both areas default to the "Blog" controller. I realize I could simply put site/{controller}/... as the url, but I would rather have it at the root if possible. I also tried keeping the default route in the global RegisterRoutes function, however, it is then not sent to the "Sites" area.

Thanks in advance!

+4  A: 

Currently it's not possible to order areas. However, I think it makes sense to try and make each area as independent from other areas as possible so the order doesn't matter.

For example, instead of having the default {controller}/{action}/{id} route, maybe replace that with specific routes for each controller. Or add a constraint to that default route.

We are mulling over options to allow ordering, but we don't want to overcomplicate the feature.

Haacked
Hey Phil, thanks for the explanation. I ended up moving my "site" out of Areas and it is now the "default/non-area" section (with Views and Controllers in root). I then set my namespace paramater to the default controllers to avoid the "ambiguous controller" error. Also, I could have probably set constraints to something like ^((?!admin).*) to ignore the admin in the site area routes. I agree, adding more complexity isn't great, although it seems mvc 1 (non area) routes could potentially rely heavily on order.Thanks!
Jason
The routing process typically depends on the rules order, so the 'ordering' feature may be important.
twk
Please see my response for two techniques that allow you to order area registration (and thus their routes) in any order.
Eilon
A: 

@haacked ran into this issue also, I think I'll end up putting my 'default area' at the root level (technically, not make it an area) but it would be nice to control the order in which areas are added to the routing table.

ampburner
That's more of a comment than an answer.
Matt Spradley
+6  A: 

Aside from what Haacked said, it is very much possible to order area registrations (and thus their routes). All you have to do is register each area manually, in whatever order you want. It's not as sleek as calling RegisterAllAreas() but it's definitely doable.

protected void Application_Start() {
    var area1reg = new Area1AreaRegistration();
    var area1context = new AreaRegistrationContext(area1reg.AreaName, RouteTable.Routes);
    area1reg.RegisterArea(area1context);

    var area2reg = new Area2AreaRegistration();
    var area2context = new AreaRegistrationContext(area2reg.AreaName, RouteTable.Routes);
    area2reg.RegisterArea(area2context);

    var area3reg = new Area3AreaRegistration();
    var area3context = new AreaRegistrationContext(area3reg.AreaName, RouteTable.Routes);
    area3reg.RegisterArea(area3context);
}

Another option is to take the code for RegisterAllAreas(), copy it into your own app, and build your own mechanism for determining the order. It is quite a bit of code to copy if you want all the fancy caching logic that the built-in method does, but your app might not even need that.

Eilon