ASP.NET MVC 4 переопределяет выданное имя и идентификатор html

Я пытаюсь изменить испускаемое имя ввода html, созданного @Html.HiddenFor.

Код, который я использую:

@Html.HiddenFor(e => e.SomeProperty, new { @id = "some_property", @name = "some_property" }

Теперь это работает для id, но не для имени. Теперь меня не волнует id, мне нужно изменить name, потому что это тот, который отправляется обратно на целевой сервер.

Здесь

  • Свойство, которое я могу применить к SomeProperty в моей модели?
  • Способ в Html.HiddenFor переопределить свойство name?

Или я застрял, чтобы сделать простой <input ...> вручную?


person Snake    schedule 11.02.2013    source источник


Ответы (4)


Вам необходимо использовать Html.Hidden (или напишите <input ...> вручную) вместо Html.HiddenFor

@Html.Hidden("some_property", Model.SomeProperty, new { @id = "some_property" })

Цель строго типизированных помощников (например, тех, имя которых заканчивается на "For", например HiddenFor), состоит в том, чтобы угадать входное имя для вас из предоставленного выражения. Поэтому, если вы хотите иметь «настраиваемое» имя ввода, вы всегда можете использовать обычные помощники, такие как Html.Hidden, где вы можете явно указать имя.

ответ от unjuken неверен, поскольку генерирует неверный HTML.

При использовании этого решения создаются ДВА name атрибута:

<input  Name="some_property"  name="SomeProperty" id="some_property" type="hidden" value="test" /> 

Таким образом, у вас будет Name="some_property" И name="SomeProperty", что является НЕДЕЙСТВИТЕЛЬНЫМ HTML, потому что ввод может иметь только ОДИН атрибут name! (хотя большинство браузеров берут первое Name="some_property" и не заботятся о втором...)

person nemesv    schedule 11.02.2013
comment
У меня была аналогичная проблема с .EditorFor(). Я использовал этот трюк, а также указал TextBox (вместо Editor). Спасибо! - person Mathieu Leblanc; 12.12.2013
comment
Вам даже не нужно включать new { @id = "some_property" }, верно? @Html.Hidden будет генерировать идентификатор, а также имя? И почему @id и @name? Также не являются ключевыми словами С#? - person nmit026; 24.02.2016
comment
@ nmit026 да, вам не нужен идентификатор и @, потому что они не являются ключевыми словами. Я только что скопировал код из вопроса в свой ответ. - person nemesv; 24.02.2016
comment
Это не работает конкретно для свойства имени, как указано в вопросе. Смотрите мой ответ. - person sovemp; 22.02.2017
comment
@sovemp Мой ответ работает, и он работает с атрибутом name: дело в том, что если вы используете Html.Hidden, первый параметр будет использоваться в качестве имени: @Html.Hidden("somePopertyName", "someValue", new { @id = "some_property" }) он будет генерировать <input id="some_property" name="somePopertyName" type="hidden" value="someValue" />, или вы можете вручную создать ввод (как я также упоминал в первая строка моего ответа), как вы также заключили... - person nemesv; 22.02.2017
comment
@nemesv О, хорошо, извини, я неправильно понял. Я отредактирую свой ответ, чтобы отразить это. Одно небольшое предложение, возможно, в вашем ответе используйте разные значения для имени и идентификатора, чтобы сделать это более очевидным, кроме some_property для обоих - person sovemp; 22.02.2017

Если вы используете:

@Html.HiddenFor(e => e.SomeProperty, new { @id = "some_property", @Name = "some_property" });

Обратите внимание на заглавную «N» в @Name. Это сработает.

person unjuken    schedule 05.06.2013
comment
Работал для меня на MVC 4 - person Pola Edward; 31.10.2013
comment
@MiniRagnarok нет, это не работает нормально. В итоге вы получите ДВА атрибута имени. Потому что приведенный выше код генерирует <input Name="some_property" name="SomeProperty" id="some_property" type="hidden" value="test" />, где у вас есть Name="some_property" И name="SomeProperty", что является НЕДЕЙСТВИТЕЛЬНЫМ HTML! (хотя большинство браузеров берут первое Name="some_property" и не заботятся о втором...) - person nemesv; 27.11.2013
comment
@nemesv Это не то, что я понимаю. Я получаю <input name="some_property" id="some_property" type="hidden" value="test">. Я не получаю два атрибута имени, я проверил источник. Это на MVC4. - person MiniRagnarok; 27.11.2013
comment
@nemesv Оказывается, Chrome не показывает мне второе имя. Он все еще работает нормально. - person MiniRagnarok; 27.11.2013
comment
-1 Это не сработает. Chrome (или любой другой браузер) исправит неправильный html, что не означает, что отображается правильный html. Пожалуйста, не используйте это. Если хром изменит метод исправления, тогда, конечно, будет отображаться неверный HTML. - person Subin Jacob; 24.12.2013
comment
Работает как шарм MVC4 (и хром) - person Michael Harper; 10.11.2014
comment
Не работает, Chrome очищает html. Понизить этот ответ - person Zac; 02.02.2015
comment
Как узнать, что браузер очищает html? Я использую MVC5, и я тестировал это в IE11, Chrome, FF и Safari 5, и все работает, как описано выше, и имя даже отображается со строчной буквой n. Если бы я не читал эти комментарии, у меня бы не было никаких мыслей по этому поводу. Я не вижу никаких сообщений браузера. В чем хитрость? - person Sum None; 21.07.2015
comment
@SumNone Этот инструмент может обнаруживать повторяющиеся атрибуты имени. - person roland; 27.08.2015
comment
Работает на меня и по сей день. Хром. МВК4. НО я отображал свойства имени, поэтому вместо этого перешел на использование @Html.Hidden(clientId, new {value = Model.Client.ID}). - person Colin Wiseman; 03.02.2016
comment
Работает с MVC5, @Name преобразуется в имя и перезаписывает существующее сгенерированное имя. - person Oswin; 30.03.2016
comment
Это как-то работает. Не уверен, почему это должно работать, - person kheya; 22.11.2016

Мне было любопытно, почему конкретное переопределение атрибута имени не сработает. Если я не написал это с заглавной буквы (т.е. new {@Name = 'somename'} ), то это, похоже, не работает. Как указывали другие, это работает только потому, что генерирует повторяющиеся атрибуты имени, а Chrome очищает их.

Я просмотрел последний исходный код MVC, чтобы понять, что происходит. Рассмотрим следующий фрагмент из метода GenerateInput в DefaultHtmlGenerator.cs:

var fullName = NameAndIdProvider.GetFullHtmlFieldName(viewContext, expression);
if (string.IsNullOrEmpty(fullName))
{
    throw new ArgumentException(
    ...
}

var inputTypeString = GetInputTypeString(inputType);
var tagBuilder = new TagBuilder("input");
tagBuilder.TagRenderMode = TagRenderMode.SelfClosing;
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("type", inputTypeString);
tagBuilder.MergeAttribute("name", fullName, replaceExisting: true);

Здесь мы видим, что проблема в том, что независимо от того, какое свойство name вы укажете, оно будет переопределено последним вызовом MergeAttribute, который будет использовать любую логику, которая присваивается переменной fullName из метода GetFullHtmlFieldName.

Я как бы понимаю, почему они применяют такое поведение, предполагая, что это как-то связано с контролем имен, используемых в обратной передаче, чтобы гарантировать, что это работает с связывателем модели.

В любом случае, чтобы это произошло, я просто создаю элемент ввода вручную и не использую помощника представления бритвы.

person sovemp    schedule 22.02.2017

никогда не работал у меня (aspnet.core)

я использовал обычный

<input type="hidden" id="@myid" name="@myname" value="@Model.prop" />

и работал как шарм. Нет необходимости в HtmlHelper HiddenForModel.

person Carl Verret    schedule 25.02.2019