Question

So I have this controller action:

public ActionResult Categories(int typecode)
{
  // code removed
}

this route:

routes.MapRoute(null,
  "{controller}/{action}/{typecode}",
  new { controller = "Search", action = "Categories", }
);

and this link to call the route:

@Html.ActionLink("Ga", "Categories", "Search", new { typecode = 16860 }, null)

if I use this, my URL is: http://localhost:50033/Search/Categories?typecode=16860 but if I change all occurences of typecode to id, it works and I get this URL: http://localhost:50033/Search/Categories/16860

So with typecode my route doesn't work and with id it does. What am I doing wrong? Thanks!

EDIT:

I think I wasn't clear enough, but in my Global.asax.cs file I have this:

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

  routes.MapRoute("TypeCode",
    "Search/Categories/{typecode}",
    new { controller = "Search", action = "Categories" }
  );
}

So that's only ONE route, than in my SearchController I have this Categories action:

public ActionResult Categories(int typecode)
{
  // Irrelevant code removed
}

So the parameter is exactly the same as the route parameter, then I have this link:

@Html.ActionLink("Ga", "Categories", "Search", new { typecode = 16860 }, null)

Also using exactly the route parameter, but still the generated link is: http://localhost:50033/Search/Categories?typecode=16860 so that's not what I want.

Now, when i replace all typecode occurences, like this:

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

  routes.MapRoute("TypeCode",
    "Search/Categories/{id}",
    new { controller = "Search", action = "Categories" }
  );
}

public ActionResult Categories(int id)
{
  // irrelevant code removed
}

@Html.ActionLink("Ga", "Categories", "Search", new { id = 16860 }, null)

It works! so I replaced everything, there are no more routes, I just replaced the 3 typecode occurences with id.

Why is this? Can anyone help me with this please? Thanks in advance!

Was it helpful?

Solution 2

The problem is solved. I will explain what went wrong for anyone who has the same issue.

I am using ASP.NET MVC 4 for this project, earlier I created some webshops with MVC 3. What I always did, was putting the routes in the Global.asax.cs file. Now, when I started my project, there was no RegisterRoutes() method, so I created one and put my routes in it. Just now I read this post and it says that MVC 4 registers its routes in App_Data/RouteConfig.cs I checked out that file, and saw the RegisterRoutes() method with one route, the default one with as optional parameter id.

So that is why it was only working with id as parameter, MVC 4 didn't even look at my route in Global.asax.cs, and just picked up the only route from App_Data/RouteConfig.cs.

I did put my route in the App_Data/RouteConfig.cs file and it works! Learned something again, and I'm glad it finally works. Also I want to say thanks to @James for helping me.

OTHER TIPS

So with typecode my route doesn't work and with id it does. What am I doing wrong?

The problem is you no doubt still have the default route being mapped before your custom route i.e.

routes.MapRoute(
    "Default",                                              // Route name
    "{controller}/{action}/{id}",                           // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);

Which means anything that matches a url similar to "controller/action/id" will be parsed by the default route, not your custom one. The fact that this route does not recognise typecode as an expected parameter means it's treated as a query string parameter (hence ?typecode=).

If you want to pick up the typecode be more specific with which controller you want to map it to and put this route before the default one i.e.

routes.MapRoute(
    "CategoryItem",
    "{controller}/Categories/{typecode}",
    new { controller = "Search", action = "Categories", typecode = UrlParameter.Optional }
);

routes.MapRoute(
    "Default",                                              // Route name
    "{controller}/{action}/{id}",                           // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);

This would constrain any urls which start like controller/Categories/ to only accept a typecode and not an id - this should result in your URL forming as Search/Categories/12345. You could constraint this further by controller if you really wanted to (just replace {controller} with Search in the route).

However, I don't see any real benefits of doing this considering you don't actually show typecode in the URL anywhere. I could understand if you were looking to show the url as Search/Categories?typecode=12345 as it's probably a bit more descriptive than id. Personally, I would leave your default route as is and change your action link to:

@Html.ActionLink("Ga", "Categories", "Search", new { id = 16860 }, null)

It will give you the same result.

Update

Based on your update, the only thing I can think of is you aren't specifying a default value in the route so perhaps it's not picking the parameter correctly, try:

routes.MapRoute("TypeCode",
    "Search/Categories/{typecode}",
    new { controller = "Search", action = "Categories", typecode = "" }
);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top