46

I have the following ActionLink in my view

<%= Html.ActionLink("LinkText", "Action", "Controller"); %> 

and it creates the following URL http://mywebsite.com/Controller/Action

Say I add an ID at the end like so: http://mywebsite.com/Controller/Action/53 and navigate to the page. On this page I have the markup I specified above. Now when I look at the URL it creates it looks like this:

http://mywebsite.com/Controller/Action/53 (notice the addition of the ID)

But I want it to remove the ID and look like it did originally, like this http://mywebsite.com/Controller/Action (notice no ID here)

Any ideas how I can fix this? I don't want to use hard coded URLs since my controller/actions may change.

1
  • 1
    See this workitem for Microsoft's official explanation of this issue and workarounds. Commented Jan 15, 2016 at 9:14

9 Answers 9

48

The solution is to specify my own route values (the fourth parameter below)

<%= Html.ActionLink("LinkText", "Action", "Controller", new { id=string.Empty }, null) %> 
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for this answer, I needed it for another circumstance but you hit the nail right on the head with that trailing null!
This seems a little kludgey... I need to do the same thing but I think I might have to create a new extension method like Arnis L posted below
Also this seems like the functionality should be built-in to the framework since this situation comes up often. For example, having a menu, you don't want the menu link to contain all of the parameters, just the action
i m using .NET 4 and mvc2 but string.empty does not solve the above mentioned problem and actionlink still keeping the ambient values
13

It sounds like you need to register a second "Action Only" route and use Html.RouteLink(). First register a route like this in you application start up:

routes.MapRoute("ActionOnly", "{controller}/{action}", new { controller = "Home", action = "Index" } ); 

Then instead of ActionLink to create those links use:

Html.RouteLink("About","ActionOnly") 

1 Comment

+1 for using Html.RouteLink(). Worked for me - you can also specify routeValues so MVC loses the current action and goes back to the index or something, eg. @Html.RouteLink("Cancel", "ThisSection_default", new { action = "Index" }).
10

The problem is the built in methods take input from the URL you are currently on as well as what you supply. You could try this:

<%= Html.ActionLink("LinkText", "Action", "Controller", new { id = ""}) %> 

That should manually wipe the id parameter.

Comments

4

If you either don't know what values need to be explicitly overridden or you just want to avoid the extra list of parameters you can use an extension method like the below.

<a href="@Url.Isolate(u => u.Action("View", "Person"))">View</a> 

The implementation details are in this blog post

2 Comments

Clean and simple, very nice +1
It's a dirty hack... but it's still the best solution I found so far.
4

I explicitly set the action name as "Action/". Seems a little like a hack but it's a quick fix.

@Html.ActionLink("Link Name", "Action/", "Controller") 

1 Comment

I had to do this as well, the link was to index, so I was able to use just "/" as the action. @Html.ActionLink("Link Name", "/", "Controller")
4

Don't know why, but it didn't work for me (maybe because of Mvc2 RC). Created urlhelper method =>

 public static string WithoutRouteValues(this UrlHelper helper, ActionResult action,params string[] routeValues) { var rv = helper.RequestContext.RouteData.Values; var ignoredValues = rv.Where(x=>routeValues.Any(z => z == x.Key)).ToList(); foreach (var ignoredValue in ignoredValues) rv.Remove(ignoredValue.Key); var res = helper.Action(action); foreach (var ignoredValue in ignoredValues) rv.Add(ignoredValue.Key, ignoredValue.Value); return res; } 

2 Comments

I had the same problem (using MVC2 RTM). I had route value called plan and the last (default) route added it as ?plan=X. So I added default value to the last (default) route for my plan route value as plan = string.Empty. Even though route definition doesn't define URL segment variable called plan. As long as it worked, I'm fine with it.
I used a variation of this to reliably and elegantly resolve this issue.
3

Another way is to use ActionLink(HtmlHelper, String, String, RouteValueDictionary) overload, then there are no need to put null in the last parameter

<%= Html.ActionLink("Details", "Details", "Product", new RouteValueDictionary(new { id=item.ID })) %> 

Comments

1

The overloads of Html.ActionLink are changed on the later versions of MVC. On MVC 5 and above. This is how to do this:

@Html.ActionLink("LinkText", "Action", "Controller", new { id = "" }, null) 

Note I passed "" for id parameter and null for HTMLATTRIBUTES.

Comments

0

I needed my menu links to be dynamic. Rather than implement a lot of extra code and routing for every single page I simple dispensed with the HTML helper.

<a href="@(item.websiteBaseURL)/@(item.controller)/@(item.ViewName)">@item.MenuItemName</a> 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.