Mariah
Mariah

Reputation: 727

MVC3 Madness - Please help binding contained collection?

I am totally at a loss here and can't find a solution to this problem. Can somebody please help provide some code to either:

I'm a complete newbie with mvc3. Here are the details...

Edit View:

    @model MVC3.Models.A

   // I need to save collection values but can't use [] here to setup model binding.
   // I have read about mapping collections but I already have a model A that is getting passed in.
   //
   @Html.EditorFor(model => model.Bs[0].Val)

Models:

public  class A
{
    public A()
    {
        this.Bs = new HashSet<B>();
    }

    public int Name { get; set; }
    public virtual ICollection<B> Bs { get; set; }  // Can't change this to ILIst because of above HashSet

 - }

       public  class B
       {
           public int Val { get; set; }  
           public virtual A A { get; set; }
       }

Upvotes: 0

Views: 285

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1039588

Your model has circular references in your view models. That's not a supported scenario by the default model binder. I would recommend you to always use editor templates in your views. Example:

Model:

public  class A
{
    public int Name { get; set; }
    public virtual ICollection<B> Bs { get; set; }
}

public class B
{
    public int Val { get; set; }
}

Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new A
        {
            Name = 123,
            Bs = new[]
            {
                new B { Val = 1 },
                new B { Val = 2 },
                new B { Val = 3 },
            }
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(A a)
    {
        // The Bs collection will be properly bound here
        return View(a);
    }
}

View (~/Views/Home/Index.cshtml):

@model A

@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(x => x.Name)
        @Html.EditorFor(x => x.Name)
    </div>
    @Html.EditorFor(x => x.Bs)
    <button type="submit">OK</button>
}

Corresponding editor template which will be rendered for each element of the Bs collection (~/Views/Home/EditorTemplates/B.cshtml):

@model B
<div>
    @Html.LabelFor(x => x.Val)
    @Html.EditorFor(x => x.Val)
</div>

Upvotes: 1

Related Questions