Reputation: 385
I have a webpage doing a redirection with two URLs parameters: id and bidId and I also have an other webpage with a redirection with two other URLs parameters: id and templateId.
I want to create the route to get a well formed url like those: localhost/12/50 but I have a problem with my routes.
routes.MapRoute(
name: "SubmitBid",
url: "{controller}/{action}/{id}/{bidId}/",
defaults: new { controller = "Tender", action = "SubmitBid", id = UrlParameter.Optional, bidId = UrlParameter.Optional });
routes.MapRoute(
name: "Tender",
url: "{controller}/{action}/{id}/{templateId}",
defaults: new { controller = "Tender", action = "Create", id = UrlParameter.Optional, templateId = UrlParameter.Optional });
When I am to the SubmitBid page the URL work perfectly but if I go to template page I have a url like this: localhost/5/?templateId=0
I don't understand why it's doesn't work and I need your help to understand why it is doing that. Thank you for your help. Karine
Edit: The way I am navigating is like this:
@Html.ActionLink(this.LocalResources("Use"), VIA.Enums.ActionName.UseTemplate.GetStringValue(), new { Id = "0", templateId = item.Id })
@using (Html.BeginForm("SubmitBid", "Tender", new { id = Model.Id, bidId = "0" }, FormMethod.Get, null))
{
<div style="text-align: center; margin: 20px 0 0 0">
<button class="btn btn-large btn-primary" type="submit">@this.LocalResources("Bid.Text")</button>
</div>
}
Upvotes: 3
Views: 16795
Reputation: 46501
You should add specific routes for both controller actions:
routes.MapRoute(
name: "SubmitBid",
url: "Tender/SubmitBid/{id}/{bidId}/",
defaults: new
{
controller = "Tender",
action = "SubmitBid",
id = UrlParameter.Optional,
bidId = UrlParameter.Optional
});
routes.MapRoute(
name: "Tender",
url: "Tender/Create/{id}/{templateId}",
defaults: new
{
controller = "Tender",
action = "Create",
id = UrlParameter.Optional,
templateId = UrlParameter.Optional
});
// Default route, keep this at last for fall-back.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
});
Upvotes: 6
Reputation: 543
I think this is your problem:
1) First, your second route you have setup is irrelevant. It will never be hit nor used to base links off of.
2) Second, because of this, when you included templateId
in your route values for the template action link,
new { Id = "0", templateId = item.Id })
ASP.Net MVC looked at your routes, found the first one that satisfied the NUMBER of parameters, then tried to resolve the optional params with the route values on the link. Since ASP.Net MVC's requirements were satisfied with the first route, the SubmitBid one, it could not find an optional parameter for the route value with a name of templateId
. It only has "Id" and "bidId" for that route. At this point ASP.Net MVC decided to stick it on the url as a query string. (This also explains why "ID", the 5 value in the url, looks correct. It is an optional param on that route.)
If you do a "view source" on your web page, you will see the link is built with that query string on there.
Here's how you might fix this:
Since your second route will never be used, delete it. Change your first route to use a more generic 2nd optional parameter:
routes.MapRoute(
name: "DefaultRoute",
url: "{controller}/{action}/{id}/{allPurposePrettyId}/",
defaults: new { controller = "Tender", action = "SubmitBid", id = UrlParameter.Optional, allPurposePrettyId = UrlParameter.Optional });
Then both your BeginForm
declaration and your ActionLink
definition will use allPurposePrettyId
in their respective route values.
@Html.ActionLink(this.LocalResources("Use"), VIA.Enums.ActionName.UseTemplate.GetStringValue(),
new { Id = "0", allPurposePrettyId = item.Id })
@using (Html.BeginForm("SubmitBid", "Tender",
new { id = Model.Id, allPurposePrettyId = "0" }, FormMethod.Get, null))
{
<div style="text-align: center; margin: 20px 0 0 0">
<button class="btn btn-large btn-primary" type="submit">@this.LocalResources("Bid.Text")</button>
</div>
}
Obviously, you should get a better name than allPurposePrettyId
but you get the gist of it. Remember the names of the optional params set on the routes are also what is expected on the signatures of the action methods the form and links goto.
Upvotes: 1