2

I have mapped route:

routes.MapRoute("test", "/{p1:int}-{p2}", new { controller = "test", action = "int" });

Such route should match int-string, like /1-stuff, and it works for such cases, however it does not work for /1-stuff-stuff. I guess this is because route is matched and then params are rejected because of int constraint.

If I remove constraints p1 equals 1-stuff, and p2 equals stuff. Is there way to apply constraints in correct way or to mark p2 as "greedy" (but not catch-all), so p1 equals 1 and p2 equals stuff-stuff?

This is very important for making human-firendly urls, where ids are at front and everything is kebab case without additional characters.

Catch-all does not work for me I need p2 to be bound to action parameter. Regex does not help.

Shadow
  • 2,089
  • 2
  • 23
  • 45
  • With slug like that it is usually advised to use the following pattern `/{id:int}/{*slug?}` similar to how StackOverflow does their URLs `/questions/50448520/aspnet-greedy-route-parameter` – Nkosi May 21 '18 at 12:11
  • Recently gave an answer along similar scenario https://stackoverflow.com/questions/50425902/add-text-to-urls-instead-of-int-id/50426483#50426483 – Nkosi May 21 '18 at 12:14
  • I stated that I do not want catch-all parameters. I need routes like `/{id:int}-{greedy-text-param}/{other-greedy-text-param}`, also catch-all cannot be placed in middle (before other parameters). – Shadow May 21 '18 at 12:32
  • You can also exclude the catch all `/{id:int}/{slug?}`. The problem with your current template is that the route table wont know which dash `-` to take. Including the id appended to the slug will cause problems to parse and match – Nkosi May 21 '18 at 12:34
  • There is enough information in route template. Id is marked as int so it should not contain any dashes, and from the other side there is slash/question mark/hash/end of url. I cannot use slug, because there are more identifiers, that should be bound to controller. – Shadow May 21 '18 at 12:37
  • Can you add the additional information to the question so that part is clear. It will improve the question and its requirements. – Nkosi May 21 '18 at 12:39
  • 1
    You could also probably look at using a `regex` constraint to match the desired pattern. Just a thought. – Nkosi May 21 '18 at 12:40
  • I've already stated it in the question, but added it second time to be clear. Also regex is no different than int. This is not a problem with constraint itself, but with parsing of incoming uri. – Shadow May 21 '18 at 12:49

1 Answers1

0

why not try something like ...

Routes.MapRoute(
    name: "test",
    url: "/{p1}",
    defaults: new { controller = "test", action = "int" },
    constraints: new { p1 = "^\d+-[\w-]*\.*$" }
);

... and then parse p1 inside your action

The regular expression might need a bit of adjusting depending on your requirement, but in this scenario p1 would be '1-stuff-stuff' then you can split("-") p1 to get your values

Thundter
  • 582
  • 9
  • 22