4

I have two routes declared in my route config like this:

routes.MapRoute(
    name: "SpecificAction",
    url: "{controller}/{action}/{id}-{id2}",
    defaults: new { controller = "Main", action = "SpecificAction", id = UrlParameter.Optional, id2 = UrlParameter.Optional }
);

routes.MapRoute(
    name: "DefaultNoParams",
    url: "{controller}/{action}/",
    defaults: new { controller = "Main", Action = "Index" },
    namespaces: new string[1] { "Project.Controllers" }
);

I have two controller actions that look like this:

[HttpGet]
public ActionResult TheAction()
{

}

[HttpPost]
public ActionResult TheAction([ModelBinder(typeof(SpecificModelBinder))] SpecificModel model)
{

}

I want a link to the first of these actions in my view, so I generate one using Url.Action:

<a href="@Url.Action("TheAction", "Main")">The Action</a>

However, this outputs the url http://site/Main/TheAction/- (note the dash at the end, which seems to indicate that my SpecificAction route is being used.

Is there some way I can call Url.Action with a specific route? Or is there any other way I can avoid this dash appearing in the url?

6
  • 1
    The routing table doesn't affect how Url.Action renders a URL... So your link is rendered as <a href="http://site/Main/TheAction/-">? Commented Feb 14, 2014 at 19:50
  • @ChrisHardie Yes, I just want to avoid that. Commented Feb 14, 2014 at 19:54
  • Odd... What is rendered when you add this to your View: <a href="@Url.Action("TheAction")">The Action</a> Commented Feb 14, 2014 at 19:57
  • @ChrisHardie Same thing... Commented Feb 14, 2014 at 20:01
  • Where is http://site coming from? Commented Feb 14, 2014 at 20:13

2 Answers 2

12

Duplicate question is found here

In short, use Url.RouteUrl() intead of Url.Action() to get the correct URL.

In your case, you can even use @Html.RouteLink() to get the whole anchor tag if you wish.

Sign up to request clarification or add additional context in comments.

Comments

4

Try to change the order of your routes. Put the SpecificAction route after the DefaultNoParams route like below:

routes.MapRoute(
    name: "DefaultNoParams",
    url: "{controller}/{action}/",
    defaults: new { controller = "Main", Action = "Index" },
    namespaces: new string[1] { "Project.Controllers" }
);

routes.MapRoute(
    name: "SpecificAction",
    url: "{controller}/{action}/{id}-{id2}",
    defaults: new { controller = "Main", action = "SpecificAction", id = UrlParameter.Optional, id2 = UrlParameter.Optional }
);

Update: To answer below requested question:

Can you provide some detail as to how the route table mappings would affect how Url.Action generates a URL such that a dash was being appended?

First, OP used below code in the view:

 <a href="@Url.Action("TheAction", "Main")">The Action</a>

it generates:

 <a href="/Main/TheAction">The Action</a>

The reason why there is a dash is because both id parameters are optional, so without both ids, there will only be a dash and it satisfies below route conditions.

routes.MapRoute(
            name: "SpecificAction",
            url: "{controller}/{action}/{id}-{id2}",
            defaults: new { controller = "Main", action = "SpecificAction", 
            id = UrlParameter.Optional, id2 = UrlParameter.Optional }
    );

If one of the ids are not optional, it'll keep checking the next routes. But OP needed the id parameters to be optional, that's why my solution is to change the route orders.

3 Comments

@Lin Can you provide some detail as to how the route table mappings would affect how Url.Action generates a URL such that a dash was being appended?
@ChrisHardie, I updated the answer to have more details, take a look.
Well, the question was how to use a specific route, not how to setup routes. This does not answer the question.

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.