Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use a specific route with Url.Action

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?

like image 954
Mansfield Avatar asked Dec 09 '22 09:12

Mansfield


2 Answers

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.

like image 180
d.popov Avatar answered Dec 11 '22 08:12

d.popov


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.

like image 36
Lin Avatar answered Dec 11 '22 09:12

Lin