Question

Sorry for the amount of code here but it's the best way to explain what;s happening.

I gave this code in my MVC 4 partial view:

  <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
  @using (Ajax.BeginForm("TestPost", new AjaxOptions { HttpMethod = "Post" }))
    {                               
        foreach (var d in Model.DataItemsWithLabels)
        {                                    
            @Html.LabelFor(m => d.DataName)
            @Html.TextBoxFor(m => d.DataValue);             
        }

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

And my controller action is as follows:

 public ActionResult TestPost(CmaPartialModel model)
 {         
        return PartialView("Transaction", model);
 }

In my model I have some code that populates a list of objects (only if they are empty) that are defined as:

 public List<DataItemWithLabel> DataItemsWithLabels { get; set; }      

    public class DataItemWithLabel
    {
        public string DisplayName { get; set; }

        public string DataName { get; set; }

        [Required]
        public string DataValue { get; set; }
    }  

I also have what think is the correct web.config entries:

I have read a load of posts here and elsewhere with no success.

The code does post to the TestPost method but the model is always empty. Can someone please tell me why this might be?

Was it helpful?

Solution

The reason you always get null value is the model binder doesn't know how to bind the list of Objects. See below example:

public class CmaPartialModel 
{
    public List<DataItemWithLabel> DataItemsWithLabels { get; set; } 
}

Then use it in you view:

@model  CmaPartialModel 

<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
@using (Ajax.BeginForm("TestPost", new AjaxOptions { HttpMethod = "Post" }))
{
    for(var i = 0; i < Model.DataItemsWithLabels.Count; i++)
     {
        @Html.LabelFor(m => m.DataItemsWithLabels[i].DataName)
        @Html.TextBoxFor(m => m.DataItemsWithLabels[i].DataValue)
     }
    <input type="submit" value="Save" />
}

Finally, your action method should be like below:

 public ActionResult TestPost(CmaPartialModel model)
 {         
        return PartialView("Transaction", model);
 }

Update

You also can use foreach in your view like below:

foreach (var item in Model.DataItemsWithLabels.Select((value, i) => new { i, value }))
{
   @Html.LabelFor(m => m.DataItemsWithLabels[@item.i].DataName)
   @Html.TextBoxFor(m => m.DataItemsWithLabels[@item.i].DataValue);   
}

OTHER TIPS

I think below code will help you.

View

@model MvcApplication1.Models.CmaPartialModel   
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Ajax.BeginForm("TestPost", new AjaxOptions { HttpMethod = "Post" }))
 {
   if (Model != null)
    {
    foreach (var d in Model.DataItemsWithLabels)
    {                                    
        @Html.LabelFor(m => d.DataName)
        @Html.TextBoxFor(m => d.DataValue);
    }
   }
  <input type="submit" value="Save" />
}

Model

public class CmaPartialModel
{
    public List<DataItemWithLabel> DataItemsWithLabels { get; set; }

    public class DataItemWithLabel
    {
        public string DisplayName { get; set; }

        public string DataName { get; set; }

        public string DataValue { get; set; }
    }  
}

Controller

public ActionResult Index()
    {
        return View();
    }
    public ActionResult TestPost(CmaPartialModel model)
    {
        List<CmaPartialModel.DataItemWithLabel> parts = new      List<CmaPartialModel.DataItemWithLabel>();
        parts.Add(new CmaPartialModel.DataItemWithLabel() {DisplayName = "abc",DataName = "cbv",DataValue = "343"});
        parts.Add(new CmaPartialModel.DataItemWithLabel() { DisplayName = "sfda", DataName = "xzfdsf", DataValue = "234" });
        model.DataItemsWithLabels = parts;
        return PartialView("Index", model);
    }

You need to modify your Post method as follows

public ActionResult TestPost(IEnumerable<DataItemWithLabel> model)
 {         
        return PartialView("Transaction", model);
 }

Since you're passing a collection of your DataItemWithLabel models to your controller.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top