56

I have the link below on a razor page:

@Html.ActionLink("Create New Profile", "Create", "Profile", new { @class="toplink" })

It appears in thes source of view page as shown below:

<a href="/admin/profile/create?length=7" class="toplink">Create New Profile</a>

When I click on the link the URL is like this:

http://localhost:54876/admin/profile/create?length=7

I don't want ?length=7. Why is this auto generated?

Trevor Reid
  • 3,310
  • 4
  • 27
  • 46
Pirzada
  • 4,685
  • 18
  • 60
  • 113
  • it must be something to do with your routes. By default, that `ActionLink` should generate a href of `/Profile/Create`. Where `Profile` is the controller argument, and `Create` is the action method argument. The fact that `/admin` is being put in the href highlights this issue. can you show your routes? – RPM1984 Dec 05 '10 at 07:43
  • you may be using the [_wrong_ overload](https://stackoverflow.com/a/61273535/1042705) – Irf Apr 17 '20 at 14:22
  • in my case it was an int and i had to add .toString() at the end and then it worked. – MindRoasterMir Mar 26 '23 at 09:19

3 Answers3

89

The ActionLink override you are using matches to the (string linkText, string actionName, Object routeValues, Object htmlAttributes) override. So your "Profile" value is being passed to the routeValues parameter. The behavior of this function with respect to this parameter is to take all public properties on it and add it to the list of route values used to generate the link. Since a String only has one public property (Length) you end up with "length=7".

The correct overload you want to use is the (string linkText, string actionName, string controllerName, Object routeValues, Object htmlAttributes) and you call it loke so:

@Html.ActionLink("Create New Profile", "Create", "Profile", new {}, new { @class="toplink"})
marcind
  • 52,944
  • 13
  • 125
  • 111
  • Can you clarify for me... using this structure, my link generates as `~/Account/Manage/` ... I had to put the empty `new { }` after my parameter, but now it generates as `~/Account/Manage/user=ortund` whereas I want `~/Account/Manage/ortund` ... I can't seem to get there and don't understand why – Ortund Sep 11 '14 at 12:40
  • 1
    Funny thing is that the official MVC bolierplate misuses this overload by default when creating a "Forgot Password" link. Had to changed it. – Hernan Demczuk Apr 04 '16 at 12:19
  • Interesting facts :) – Aravin Apr 11 '18 at 17:19
7

I'm not sure the exact cause of this, but change it to:

@Html.ActionLink("Create New Profile", "Create", "Profile", new {}, new { @class="toplink" })

I don't know which overload MVC is picking when you leave off the last parameter (htmlattributes is the added one), but that will fix it. One of these days I'll investigate and figure out exactly what's going on.

Brian Ogden
  • 18,439
  • 10
  • 97
  • 176
Matt Sieker
  • 9,349
  • 2
  • 25
  • 43
  • This sort of worked for me, but I still ended up with a bum link... I got `~/Account/Manage/user=ortund` whereas what I need is `~/Account/Manage/ortund` – Ortund Sep 11 '14 at 12:46
  • You can just use null. At least that is what I always use. – Cheesus Toast Aug 04 '15 at 17:35
1

Another thing to note, since you are defining the controller in the @ActionLink, which you may not need to do, for example, the view that your "Create New Profile" @ActionLink is expressed in might be "/admin/profile/index.cshtml", a view that lists existing profiles, in this case, you do not need to define the controller in the @ActionLink as the @ActionLink is already relative to the ProfileController, so your @ActionLink could be

@Html.ActionLink("Create New Profile", "Create", null, new { @class="toplink" })

I used null instead of new{} as the marked answer does, I think this is more appropriate myself. ActionLink overloads are not the most straightforward thing ever.

Brian Ogden
  • 18,439
  • 10
  • 97
  • 176