Reputation: 1558
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!
Upvotes: 0
Views: 1361
Reputation: 1558
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.
Upvotes: 1
Reputation: 82136
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 = "" }
);
Upvotes: 2