ASP.NET MVC 4 override emitted html name and id

asp.net Mvcasp.net Mvc-4Razor 2

asp.net Mvc Problem Overview


I'm trying to change the emitted name of the html input created by @Html.HiddenFor.

The code I'm using this:

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

Now this works for the id, however it doesn't work for the name. Now I don't really care for the id now, I need the name to change, because that's the one that get's posted back to the target server.

Is there

  • A property I can apply on SomeProperty in my model?
  • A way in the Html.HiddenFor to override the name property?

Or am I stuck to do a plain <input ...> by hand?

asp.net Mvc Solutions


Solution 1 - asp.net Mvc

You need to use the Html.Hidden (or write out the <input ...> by hand) instead of the Html.HiddenFor

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

The goal of the strongly typed helpers (e.g the one which the name end "For" like HiddenFor) is to guess the input name for you from the provided expression. So if you want to have a "custom" input name you can always use the regular helpers like Html.Hidden where you can explicitly set the name.

The answer from unjuken is wrong because it generates invalid HTML.

Using that solution generates TWO name attributes:

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

So you will have Name="some_property" AND name="SomeProperty" which is INVALID HTML because an input can only have ONE name attribute! (although most browers happen to take the first Name="some_property" and don't care about the second one...)

Solution 2 - asp.net Mvc

If you use:

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

Notice the capital "N" in @Name. It´ll work.

Solution 3 - asp.net Mvc

I was curious as to why specifically overriding the name attribute wouldn't work. Unless I capitalized it (i.e. new {@Name = 'somename'} ), then it doesn't seem to work. As others have pointed out, this only works because it generates duplicated name attributes and Chrome cleans it up.

I looked at the latest MVC source code to figure out what is going on. Consider the following snippet from the GenerateInput method in 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);

We can see here, the problem is that, regardless of whatever name property you provide, it will be overridden by the last call to MergeAttribute, which will use whatever logic it is that assigns to the variable fullName from the GetFullHtmlFieldName method.

I sort of understand why they enforce this behavior, guessing it has something to do with controlling the names used in the postback to guarantee it works with the model binder.

In any case, to make this happen, I say just manually construct the input element and don't use the razor view helper.

Solution 4 - asp.net Mvc

never worked for me (aspnet.core)

I used plain

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

and worked like a charm. No need for HtmlHelper HiddenForModel.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSnakeView Question on Stackoverflow
Solution 1 - asp.net MvcnemesvView Answer on Stackoverflow
Solution 2 - asp.net MvcunjukenView Answer on Stackoverflow
Solution 3 - asp.net MvcsovempView Answer on Stackoverflow
Solution 4 - asp.net MvcCarl VerretView Answer on Stackoverflow