Чому Html.ActionLink відображає "? Довжина = 4"


305

Я ДУЖЕ заплутався, чому цей код

Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" })

результати за цим посиланням:

<a hidefocus="hidefocus" href="/Home/About?Length=4">About</a>

hidefocusЧастина того, що я прагнув досягти, але де ж ?Length=4взялося?


4
Така поведінка також з’являється за допомогою методів Html.BeginForm ().
Джонатан Уотні

Відповіді:


326

Довжина = 4 походить від спроби серіалізації рядкового об'єкта. У вашому коді працює цей ActionLinkметод:

public static string ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes)

Для цього потрібен stringоб’єкт "Головна" для routeValues, який водопровід MVC шукає загальнодоступні властивості, перетворюючи їх у значення маршруту. У випадку з stringоб'єктом єдиним загальнодоступним властивістю є Length, і оскільки не буде маршрутів, визначених параметром Length, він додає ім'я властивості та значення як параметр рядка запиту. Ви, ймовірно, знайдете, якщо запустити це зі сторінки, а не на HomeControllerній, ви видасте помилку щодо відсутнього Aboutметоду дій. Спробуйте використовувати наступне:

Html.ActionLink("About", "About", new { controller = "Home" }, new { hidefocus = "hidefocus" })

@Blah_Blah в ці дні я цим взагалі не користуюся, вважаю за краще писати власні теги <a> та просто використовувати Url.Action ("Дія", "Контролер")
roryf

@roryf не хвилюйтесь ... це було використано в огляді коду як найкраща практика, вони не перевіряли дату. Справді має бути спосіб фільтрації
потоку потоку

Чудова відповідь. Просто додати це також відбувається на Html.BeginRouteForm з тієї ж причини. Html.BeginRouteForm ("Маршрут", "Дія", FormMethod.Post)) повинен бути Html.BeginRouteForm ("Маршрут", новий {action = "AgentSignUp"}, FormMethod.Post), який позбавляється від дивної речі довжини
radm4

Також трапляється з Url.Action(). Якщо змінити, Url.Action("Action", "Controller", new { area = "" })щоб Url.Action("Action", new { controller = "Controller", area = "" })не відображати властивість Length.
Джон Вашам

Щоб уникнути подібних ситуацій, ви завжди можете вказати, які параметри ви проходите, як-от:Html.ActionLink("About", "About", "Home", routeValues: null, htmlAttributes: new { hidefocus = "hidefocus" })
Epiplon

195

Я вирішив це шляхом додавання нуля до четвертого параметра перед анонімним оголошенням ( new {}), щоб він використовував такий метод перевантаження: (linkText, actionName, controllerName, routeValues, htmlAttributes):

Html.ActionLink("About", "About", "Home", null, new { hidefocus = "hidefocus" })

Це найкраща відповідь, якщо ви не зв’язуєтесь між областями. Якщо вам потрібно вказати область для посилання, вам слід вказати routeValues ​​з controllerі і, areaщоб утримати властивість Length не відображатися в URL-адресі.
Джон Вашам

@JohnWasham Насправді, вам не потрібно вказувати контролер, routeValuesа лише область. Наприклад:Html.ActionLink("About", "About", "Home", new {@area = "Admin"}, new { hidefocus = "hidefocus" })
Epiplon

1
@epiplon, тому я визначаю контролер так, що якщо ви ніколи не включаєте htmlAttributes як останній аргумент ActionLink, MVC буде включати дивний Length=xпараметр в кінці URL-адреси. Наприклад, помістіть це на сторінку, потім перегляньте джерело вашої сторінки, і ви побачите, що я маю на увазі: @Html.ActionLink("About", "About", "Home", new { area = "Admin" }, new { hidefocus = "hidefocus" }) @Html.ActionLink("About", "About", "Home", new { area = "Admin" }) Але якщо ви введете controllerзапис у routeValues, він ніколи не поставить Length=xу URL-адресу.
Джон Вашам

@epiplon, ви також не повинні використовувати @в @area = "Admin", тільки так ви знаєте.
Джон Вашам

88

Ви забули додати парм HTMLAttributes.

Це буде працювати без будь-яких змін:

Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" },null)

Я не знаю, чому це не працює для мене. Я спробував "new {hidfocus =" "}", і це працює для мене.
Naredla Nithesh Reddy

28

Параметри для ActionLink невірні, вона намагається використовувати значення "Головна" як значення маршруту замість анонімного типу.

Я вважаю, що вам просто потрібно додати new { }або nullяк останній параметр.

EDIT: Просто перечитайте публікацію і зрозумівши, що ви, ймовірно, захочете вказати null як другий останній параметр, а не як останній.


1
BTW Вони повинні видалити один метод, оскільки використовувати його неможливо!
Марк Клімент

5
Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" }, new { })

Це призведе до перевантаження: string linkText, string actionName, string controllerName, Object routeValues, Object htmlAttributes


3

Будь ласка, використовуйте правий перевантажений метод з п'ятьма (5) параметрами. Приклад:

@using (@Ajax.BeginForm("Register", "Account", null,
    new AjaxOptions
    {
        HttpMethod = "POST",
        OnSuccess = "OnSuccess",
        OnFailure = "OnFailure",
        OnBegin = "OnBegin",
        OnComplete = "OnComplete"
    }, new { @class = "form-login" }))

додавання нуля після імені контролера було корисним у моєму випадку.
Мунам Юсуф

Це фактично та сама відповідь, що і відповідь @ Jesse з додатковим бонусом, що він охоплює версію Ajax, що не те, про що вимагала ОП, але це пов'язано з тим же питанням.
gcoulby

2

Просто видаліть "Головна" (ім'я контролера), щоб код був:

Html.ActionLink("About", "About", new { hidefocus = "hidefocus" })

1

Імена атрибутів:

 @Html.ActionLink(linkText: "SomeText", actionName: "SomeAction", controllerName: "SomeControllerName", routeValues: new { parameterName = parameterValue}, htmlAttributes: null)

0

Як в коментарі зазначив Джонатан Уотні, це також стосується

Html.BeginForm ()

методи. У моєму випадку я був у Create.cshtml націлюванні на запит на повідомлення відповідного контролера + Створити дію і мав

using (Html.BeginForm("Create")) {
  @Html.AntiForgeryToken()
  ...
}

який додавав рядок запитів "? length = 6" до дії форми при наданні. Натякнувши схвалену відповідь Роріфа і зрозумівши, що довжина рядка "Створити" дорівнює 6, я остаточно вирішив це, видаливши явну специфікацію дії:

using (Html.BeginForm()) {
      @Html.AntiForgeryToken()
      ...
    }

0

Можливо, інші мали таку саму проблему, і їм потрібно надати значення класу за допомогою parm HTMLAttributes . Ось моє рішення:

@Html.ActionLink("About", "About", new { controller = "Home", area = "" }, new { hidefocus = "hidefocus", @class = "nav-item nav-link" })


0

Шукати відповідь на моє запитання висадило мене сюди, в основному це важливий вибір правильного перевантаження @Html.ActionLink введіть тут опис зображення .
Я відбирав перевантаження , яка не існує, ( без останньої null ), і MVCне було такого перевантаження, в результаті помилкового URL що - щось на зразок ОП згадується.

Приватне примітка: ви можете useанонімні типи не означає , що ви можете використовувати будь-який з overloads- у яких не існує? - переконайтесь: це має бути визначено!
- Прийшов сюди за часів MVC 5.2

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.