3

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>
}
2
  • How are you going to the Template page? Can you post code that shows how you are navigating? Commented Oct 25, 2013 at 3:19
  • 1
    If you need more information just let me know. Thank you for your time :) Commented Oct 25, 2013 at 4:30

2 Answers 2

6

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 
                });
Sign up to request clarification or add additional context in comments.

1 Comment

The controller action is not the issue as the OP is always giving an action on the URL. The OP is not having a problem varying routes by action. The question was about varying the parameter name that is passed. You should not create a new route for this. Generic parameter names are what is needed. If every time the {id} parameter had a new purpose the route creation would be out of control.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.