5

I am using Attribute Routing in MVC4 application. I have set route to [Route("test-{testParam1}-{testParam2}")]. Here `{testParam2}' may consist the word 'test'. For example, if I enter a url as below,

localhost:33333/test-temp-test-tempparam2

This gives me 404 error. Here in the url, here {testParam2} is having two words test tempparam2 formatted to test-tempparam2. When test word is at last position of {testParam2}, it runs good. That means if the url is like .../test-temp-tempParam2-test runs good. But following give error. .../test-temp-test-tempParam2.

Below is the code that may help...

[Route ("test-{testParam1}-{testParam2}")]
public ActionResult Foo (int testParam2) {...}

Now try following two url.

  1. localhost:(port)/test-temp-1

  2. localhost:(port)/test-test-temp-1

In my case second gives error. In this case first parameter is formatted to test-temp from test temp. First runs good.

How to solve this problem?

Nkosi
  • 235,767
  • 35
  • 427
  • 472
DhavalR
  • 1,409
  • 3
  • 29
  • 57
  • Can you use {testparam2} as test_tempparam2 – kgzdev Jan 19 '17 at 08:13
  • Have a look at this project on GitHub. It is distributed as a nuget package. https://github.com/AtaS/lowercase-dashed-route – jvanrhyn Jan 19 '17 at 09:02
  • @DhavalR provide a [mcve] that can be used to reproduce the problem. That way it can be used to find better answers. – Nkosi Jan 22 '17 at 04:11
  • @NKosi please see edit. – DhavalR Jan 22 '17 at 04:16
  • 4
    Your controller method route is accepting two parameters delimited by a dash. So why are you passing 3 parameters in your URL? If your parameter has a dash, how do you expect the router to distinguish which is a delimiter and which is legitimately part of your parameter? – Frank Fajardo Jan 22 '17 at 04:21
  • What is the error that you are getting in second case? – kevalsing Jan 22 '17 at 04:26
  • @DhavalR, I tested it and received 200 OK response for both URLs in OP. Unable to reproduce the 404 Not Found error. – Nkosi Jan 22 '17 at 04:29
  • @DhavalR when tested route data shows `testParam1=temp-temp2, testParam2=test` for the first URL and `testParam1=temp-test, testParam2=temp2` for the second URL. – Nkosi Jan 22 '17 at 04:39
  • @FrankFajardo That's true. Actually I am not passing three parameters. The second param is formatted. eg. `tempParam2 = "test foobar"` than it's formatted to `test-foobar`. – DhavalR Jan 22 '17 at 04:54
  • @Nkosi Please see the edit. Can you try both url again. I apologize for taking more time. Actual problem is when we use last parameter as int in method. I forgot to mention it. – DhavalR Jan 22 '17 at 05:01
  • 1
    @DhavalR, I don't need to test it again. If you had included that information up front I would have been able to tell you to use a route constraint. `[Route ("test-{testParam1}-{testParam2:int}")]` – Nkosi Jan 22 '17 at 05:14
  • @DhavalR what was the final outcome? Has this been resolved? – Nkosi Jan 25 '17 at 19:41

2 Answers2

2

OP indicated that the last parameter in the route template is an int

Use a route constraint.

Route constraints let you restrict how the parameters in the route template are matched. The general syntax is {parameter:constraint}. For example:

[Route ("test-{testParam1}-{testParam2:int}")]
public ActionResult Foo (int testParam2) {...}

Thus, when trying following two URLs.

localhost:(port)/test-temp-1

localhost:(port)/test-test-temp-1

The first would match route data {testParam1 = temp}-{testParam2 = 1}

And the second would match route data {testParam1 = test-temp}-{testParam2 = 1}

Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • Well, I learnt about `constraint` in `Attribute Routing`. Your example and explanation is good. But I will go with `FrankFajardo's` comment. Because your code(url) works as you mentioned. But when it comes when `{tempParam1}` has more than two characters (e.g. temp-test-temp), it will throw error. If you have url like `test-temp-test-2`, then it will work. But when it's `test-temp-test-temp-2`, won't work. So had to change my `Attribute Route` like `~/{tempParam1}-{tempParam2}` or `test/{tempParam1}-{tempParam2}`. BTW Thanks for your answer and explanation. – DhavalR Jan 27 '17 at 10:04
1

Do you have the following piece of code in you Global.asax file?

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);

    routes.MapMvcAttributeRoutes();

    routes.MapRoute(
        name: “Default”,
        url: “{controller}/{action}/{id}”,
        defaults: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional }
    );
}
ilya korover
  • 230
  • 1
  • 3