0

So I have two URLs that I need separate routes for:

/find-your-new-home/155-detroit/1234-some-value

and

 /find-your-new-home/155-detroit/5555g-some-other-flipping-value

The route I have in place to handle #1 is:

routes.MapRoute(
                "FindYourNewHomeCommunity",
                "find-your-new-home/{market}/{community}.html",
                new { controller = "Community", action = "Detail" }
                );

I have an action filter on the "Detail" method that splits "155" from "detroit" and also splits "1234" from "some-flipping-value" and passes just the ID's to the action method (the id's are all that matter, the text values are inconsequential).

Now, the second route is almost exactly the same EXCEPT that there is a "g" after the "5555" value. This "g" indicates that it should call another action method ("CommunityGroup") on the Community Controller.

My question is: how do I configure two routes to handle these separately? I tried:

routes.MapRoute(
                    "FindYourNewHomeCommunityGroup",
                    "find-your-new-home/{market}/{communityId}g-{community}.html",
                    new { controller = "Community", action = "CommunityGroup" }
                    );

That doesn't work however, for two reasons:

1) Both URLs end up matching both routes as proven by Phil Haack's RouteDebugger.

2) Because of greedy matching (and this is why I used the text "flipping-value" in the sample URL), communityId ends up containing "5555-some-other-flippin" since it matches to the last occurrence of "g-" in the URL, which happens to be in the "flipping-value" text.

So my question is, how do I get a different action method to fire for these URLs?

EDIT: Just to clarify, these URLs are pre-defined by some other constraints I'm working in and cannot be changed. They have to follow exactly this format.

Scott
  • 13,735
  • 20
  • 94
  • 152
  • 1
    You could implement your own route handler and avoid greedy matches. I don't have a code sample to hand as I'm jut leaving the office but if nobody else replies, I'll try to dig something out this evening. – Basic Feb 24 '11 at 21:14

2 Answers2

1

You could try creating a route constraint so that the "communityId" part of the route would only match numeric characters, eg:

routes.MapRoute(
    "FindYourNewHomeCommunityGroup",
    "find-your-new-home/{market}/{communityId}g-{community}.html",
    new { controller = "Community", action = "CommunityGroup" },
    new { communityId = @"\d+" }
);
Danny Tuppeny
  • 40,147
  • 24
  • 151
  • 275
  • Actually I had that same thought and tried it out with the exact same syntax you suggested, but because of the greedy matching, it's not always numeric. In the case of my second URL, the communityId would contain "5555g-some-other-flippin" which is obviously not numeric. :) – Scott Feb 24 '11 at 21:45
  • I don't understand - the constraint should force the route to match with communityId being numeric, it wouldn't match the other way? – Danny Tuppeny Feb 24 '11 at 21:47
  • Just looking at the route, you would THINK that communityId would contain only "5555" and should therefore match the constraint. However, route matching is greedy, aince since there's another "g-" in the URL ("some-other-flipping-value" - the last "g" in flipping", communityId actually contains "555g-some-other-flippin". – Scott Feb 24 '11 at 21:57
  • The constraint should stop communityId ever containing "555g-some-other-flippin"? – Danny Tuppeny Feb 24 '11 at 22:22
  • is that constraint right, or is it just matching string which start with numeric characters? – Massif Feb 25 '11 at 13:51
  • The constraint is saying the communityId parameter must be 1 or more digits. The regex here is effectively replaced into the route when it matches them up and sets the arguments – Danny Tuppeny Feb 25 '11 at 13:56
0

If you can generate a list of communities, then you can write a custom regex constraint that will look up the communities at runtime and find them for you. It will then construct the constraint to only catch routes that match what you're looking for for the communities. One potential problem with it is that it only works on Application_Start. It'd be nice to change it dynamically. You could probably do it by updating the RouteTable.Routes at runtime when there are changes, but that is hacky.

Anyway, I ended up answering another Stack Overflow question that covered the same ground, here's the answer I wrote there.

Community
  • 1
  • 1
George Stocker
  • 57,289
  • 29
  • 176
  • 237