Creating HiddenFor IEnumerable<String> in View

user547794 picture user547794 · Oct 19, 2012 · Viewed 14.3k times · Source

I have a Property that is an IEnumerable

public IEnumerable<string> ChangesOthersResult { get; set; }

I need to collect all values from ChangesOthersResult and post from a view back to the controller. How can I loop through the Ienumerable and create hidden fields that will bind back to the ViewModel in the controller?

foreach(var item in Model.ChangesOthersResult)
   {
       @Html.HiddenFor(x => x.ChangesOthersResult);
   }

Is giving me the Raw SQL statement as text.

Answer

GitteTitter picture GitteTitter · Oct 22, 2013

I made this into an extension method so the for loop doesn't uglify your view code:

public static class HiddenExtensions
{
    public static MvcHtmlString HiddenForEnumerable<TModel, TProperty>(this HtmlHelper<TModel> helper,
        Expression<Func<TModel, IEnumerable<TProperty>>> expression)

    {
        var sb = new StringBuilder();

        var membername = expression.GetMemberName();
        var model = helper.ViewData.Model;
        var list = expression.Compile()(model);

        for (var i = 0; i < list.Count(); i++)
        {
            sb.Append(helper.Hidden(string.Format("{0}[{1}]", membername, i), list.ElementAt(i)));
        }

        return new MvcHtmlString(sb.ToString());
    }
}

GetMemberName is another extension method:

    public static string GetMemberName<TModel, T>(this Expression<Func<TModel, T>> input)
    {
        if (input == null)
            return null;

        if (input.Body.NodeType != ExpressionType.MemberAccess)
            return null;

        var memberExp = input.Body as MemberExpression;
        return memberExp != null ? memberExp.Member.Name : null;
    }

Hope this is helpful.