Question

I'm trying to use the default model binder in asp.net mvc to bind a list of hidden fields

<input id="entity" name="entity" type="hidden" value="/string/one/here" />
<input id="entity" name="entity" type="hidden" value="/another/string/here" />
<input id="entity" name="entity" type="hidden" value="/last/string/here" />

To a List<string> like this:

    [HttpPost]
    public ActionResult Move(List<string> entity)
    {
        return View(entity);
    }

When I post the form, the view displays the contents of the list like this:

        <%foreach (string item in Model)
          {%>

          <%: Html.Hidden("entity", item)%>
          <!--binding not working correctly -->

        <%} %>

And the generated content is this:

<input id="entity" name="entity" type="hidden" value="/last/string/here" />
<input id="entity" name="entity" type="hidden" value="/last/string/here" />
<input id="entity" name="entity" type="hidden" value="/last/string/here" />

I'm confuseled. I tried changing the initial hidden field to this:

<input id="entity__" name="entity[]" type="hidden" value="/string/one/here" />
<input id="entity__" name="entity[]" type="hidden" value="/another/string/here" />
<input id="entity__" name="entity[]" type="hidden" value="/last/string/here" />

But when I tried posting that I got this error:

 System.NullReferenceException: Object reference not set to an instance of an object.

on this line of code in the view:

<%foreach (string item in Model)

I've been able to bind list of strings before... without using an index in the name. I don't understand why this isn't working correctly. Maybe a fresh set of eyes could help me out with this?

Thanks

edit

In continuing to expirement. I ditched the HtmlHelper and hardcoded a hidden field inside the foreach loop like this:

<%foreach (string item in Model)
  {%>
      <input id="entity" name="entity" type="hidden" value="<%:item %>" />
<%} %>

This worked. I have no idea what the difference is between the Html helper's code and this so I put the two side by side and tried to match them up.

<input id="entity" name="entity" type="hidden" value="//Content/files/NewDirectory/Aesculuparviflora011cm.jpg" />
<input id="entity" name="entity" type="hidden" value="//Content/files/NewDirectory/Aesculuparviflora011cm.jpg" />

They are identical. But the binding works when I hardcode tags and it doesn't work when i use the html helper. What gives?????????

Was it helpful?

Solution

Why are you using loops and non-strongly typed helpers in a strongly typed view? Things could be so simple with editor templates:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new[] 
        {
            "/string/one/here", "/another/string/here", "/last/string/here"    
        });
    }

    [HttpPost]
    public ActionResult Index(List<string> items)
    {
        return View(items);
    }
}

and the corresponding view (~/Views/Home/Index.aspx):

<%@ Page 
    Title="" 
    Language="C#" 
    MasterPageFile="~/Views/Shared/Site.Master" 
    Inherits="System.Web.Mvc.ViewPage<IEnumerable<string>>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <% using (Html.BeginForm()) { %>
        <%: Html.EditorForModel() %>
        <input type="submit" value="OK" />
    <% } %>
</asp:Content>

and the corresponding editor template (~/Views/Home/Index/EditorTemplates/string.ascx):

<%@ Control 
    Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<%: Html.HiddenFor(x => x) %>

Now you no longer need to worry about values not properly binding, writing loops in your views, ... you can finally concentrate on the real business logic of the application.

OTHER TIPS

try:

<input id="entity" name="entity0" type="hidden" value="/last/string/here" /> 
<input id="entity" name="entity1" type="hidden" value="/last/string/here" /> 
<input id="entity" name="entity2" type="hidden" value="/last/string/here" /> 

I actually cannot recreate your problem: This is my code, I tried fiddling with it and I cannot get it to malfunction. perhaps check so that your view inherits the right type. Please post all of your code neccessary to make it malfunction.

    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        var strings = new string[] { "test1", "test2", "test3" };

        return View(strings);
    }

    [HttpPost]
    public ActionResult Index(List<string> strings)
    {

        return View(strings);
    }

aspx page

       <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<string>>" %>
        <%using (Html.BeginForm()) { %>

        <% foreach (var item in Model) { %>

            <%:Html.Hidden("strings", item)%>   

        <% } %>

        <input type="submit" value="Submit" />
    <% } %>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top