Reputation: 21822
When I use Html.ActionLink() the URL created is not in the desired format:
Html.ActionLink(Model.ProductCode, "Update", new { id = Model.ProductId })
Makes this URL
/Update?id=1
When I want to have this URL:
/Update/1
What routing options create the 2nd URL? This is our preferred URL style.
Both URLs work and the correct page is displayed - however we want to only use /id
In Global.asax the MVC default route handles both URLs
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }); // Parameter defaults
Upvotes: 6
Views: 2981
Reputation: 2601
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Upvotes: 0
Reputation: 1
I've just stumbled upon this and decided to answer. It turned out that both Url.Action() and Html.ActionLink() use the first route in the route collection to format the resulted URL. So, the first mapped route in the RegisterRoutes() shoild be:
routes.MapRoute(
name: "Default",
url: "{controller}/{id}/{action}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
instead of "{controller}/{action}/{id}". The route name (i.e. "Default") does not matter, only the order does matter
Upvotes: 0
Reputation: 1216
See This question/answer.
Which version of MVC are you using? If you're in MVC3, you'll need to add a fourth parameter to your call to Html.ActionLink()
, passing in a null
.
Upvotes: 0
Reputation: 39807
I can replicate the issue by having a route about my default route that still matches the general pattern. Example:
routes.MapRoute(
"Default2", // Route name
"{controller}/{action}", // URL with parameters
new { controller = "Home", action = "Index"} // Parameter defaults
);
When places above my default route, I get the ?id=1 in my URL. Can you confirm that this ActionLink is not matching any routes above the route that you are expecting it to match?
EDIT: The below does not impact the URL
However, it could still be advantageous to use the UrlParameter.Optional in other scenarios. Leaving for prosperity unless mob rule says otherwise.
new UrlParameter.Optional value. If you set the default value for a URL parameter to this special value, MVC makes sure to remove that key from the route value dictionary so that it doesn’t exist.
I think you need to adjust your route slightly. Change id = "" to id = UrlParameter.Optional
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
This is what we use for the default route and the behavior that you are looking for is how our applications behave.
Upvotes: 2