@Html.Hiddenfor Does Not Work on Lists in ASP.NET MVC

@Html.HiddenFor does not work on Lists in ASP.NET MVC

I've just come across this issue and solved it simply by doing the following:

@for(int i = 0; i < Model.ToGroups.Count; i++)
{
@Html.HiddenFor(model => Model.ToGroups[i])
}

By using a for instead of a foreach the model binding will work correctly and pick up all of your hidden values in the list. Seems like the simplest way to solve this problem.

Passing a List as @Html.Hidden and the list is being deleted

Instead of returning one item, you're looking for returning a list.

One way to do that is returning an array of form elements with the same name, so the controller can stitch that back into a list.

Here's an example:

Instead of:

@Html.Hidden("basketItems", Model.BasketItems)

Add this:

for (int i = 0; i < Model.BasketItems.Count; i++)
{
@Html.HiddenFor(m => m.BasketItems[i])
}

This will generate the following html:

<input type="hidden" name="basketItems[0]" value="item 1" />
<input type="hidden" name="basketItems[1]" value="item 2" />

(maybe you don't need the @ in the @Html, but I haven't checked that)

update
I created a test project:

TestViewModel.cs

using System;
using System.Collections.Generic;

namespace WebApplication1.Models
{
public class TestViewModel
{
public string Name { get; set; }
public List<String> Items { get; set; }
}
}

HomeController.cs

using System.Collections.Generic;
using System.Web.Mvc;
using WebApplication1.Models;

namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
var viewModel = new TestViewModel {
Name = "Test name",
Items = new List<string> { "item 1" , "item 2" }
};

return View(viewModel);
}

[HttpPost]
public ActionResult Index(string name, List<string> items)
{
var viewModel = new TestViewModel
{
Name = name,
Items = items
};
return View(viewModel);
}

}
}

Index.cshtml

@model WebApplication1.Models.TestViewModel
@{
ViewBag.Title = "Home Page";
}

@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{

for (int i = 0; i < Model.Items.Count; i++)
{
@Html.HiddenFor(m => m.Items[i])
}

<div class="">
@Html.TextBoxFor(m => m.Name)
</div>

<input type="submit" value="save" />
}

When I click save, the form is displayed again but now with the values from the previous form

input type=hidden asp-for= does not work for List

After some searching and experimenting I figured out a nice solution.

I created two extension methods SerializeForHidden and DeserializeForHidden (see below) and added an extra property in the view model:

public string UserLevelsHidden
{
get => UserLevels.SerializeForHidden();
set => UserLevels = value.DeserializeForHidden(UserLevels);
}

Now the values of UserLevels are saved in the form and re-created at the post with:

<input type="hidden" asp-for="UserLevelsHidden"/>

This will work for any serializable type, not just for Lists.

Extension methods:

using Newtonsoft.Json;
using System.Web;

namespace Forestbrook.Web
{
public static class WebHelper
{
/// <summary>
/// Deserialize a value from a hidden HTML Form field which was serialized
/// with SerializeForHidden to its original type.
/// </summary>
/// <typeparam name="T">Type to deserialize to</typeparam>
/// <param name="value">serialized and HtmlEncoded string from HTML form</param>
/// <param name="_">Target property only used to simplify detection of T. May be null.</param>
/// <returns>Deserialized object or null when value was null or empty</returns>
public static T DeserializeForHidden<T>(this string value, T _)
{
if (string.IsNullOrEmpty(value))
return default;

return JsonConvert.DeserializeObject<T>(HttpUtility.HtmlDecode(value));
}

/// <summary>
/// Serialize a complex value (like a List) to be stored in a hidden HTML Form field
/// </summary>
/// <param name="value">Value to serialize</param>
/// <returns>Json serialized and HtmlEncoded string</returns>
public static string SerializeForHidden(this object value)
{
if (value == null)
return null;

return HttpUtility.HtmlEncode(JsonConvert.SerializeObject(value,
new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }));
}
}
}

Mind that the T _ parameter in DeserializeForHidden is only added to make the use of DeserializeForHidden easier. You can remove it if you like, but then you always have to specify the type.

MVC Html.HIddenFor value not being passed to the model

At the moment, the hidden field DateAvailable will always be set to null. When you click a date from the data picker, it isn't currently updating the hidden field.

So, instead of

$(function () {
$("#datepicker").datepicker();
});

try:

$(function() {
$("#datepicker").datepicker({
dateFormat: 'dd-mm-yy',
onSelect: function (dateText, e) {
$("#DateAvailable").val($(this).val());
}
});
});

This will assign the hidden field a value. Also, as discussed in our conversion, the date would need to be formatted, as defined by dateFormat: 'dd-mm-yy' above.

Why mvc Html.HiddenFor does not render my field?

I'm not sure if this is the case with you but the Html.HiddenFor() "do not output correct values after a post if the value is changed during the post." and this is a not a bug it was designed that way.

Quick Fix :

Don't use the helper, try this instead :

<input type="hidden" value="<%= Html.AttributeEncode(model.Id) %>" id="Id" name="Id" />

Always worked for me :)

MVC 4 HiddenFor field not appearing in rendered markup

You need to add a @, @Html.HiddenFor(). Otherwise you're just executing the helper method, but not actually doing anything with the output.

How to fix RazorEngine issue with Html.HiddenFor

I found this answer by warabino:

And what I did was that I copied that dll from C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6.1\System.Core.dll and I pasted these lib into my project bin.
Later u can see that inside your project the dll is added automatically in the reference.

I did alike (using the dll from C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5) and that solved the issue.

However, I do not know whether the dll (and its reference) was present in my project before and got lost or became necessary after some updates I made.



Related Topics



Leave a reply



Submit