0

Here is my scenario:

public class ComplexObject
{
   public int SomeProperty {get;set;}
   public List<SimpleObject> Object {get;set;}
}

public class SimpleObject
{
public string FirstName {get;set;}
public string LastName {get;set;}

}

I created a strongly typed partial view for SimpleObject

@model SimpleObject
    <div>
        <input type="button" value="Button" name="btn" />
        <div>
            <div>
                @Html.TextBoxFor(Model => Model.FirstName, new { @class = "", @maxlength = "50" })
            </div>
            <div>
                @Html.TextBoxFor(Model => Model.LastName, new { @class = "", @maxlength = "50" })
            </div>

Now I want to Render this partial view inside another view (MainView). The idea is that a user can click SimpleObject partial view button and generate the same partial view again on the MainView . SO here is how it looks :

MainView
    SimpleView -> Add
        SimpleView -> Add

I can create an ajax action and generate the simple view and append it to mainview but the problem is that simpleobject is NOT binding to the ComplexObject.

This is how I render partialview in MainView.

 @Html.Partial("_PartialView", Model.SimpleObject, new ViewDataDictionary(ViewData)
{
    TemplateInfo = new System.Web.Mvc.TemplateInfo
    {
        HtmlFieldPrefix = "Simple"
    }
})

The MainView calls a controller action on submit click and the entire ComplexObject is submitted. Here my List of SimpleObject is always NULL.

 public ActionResult CreateComplex(ComplexObject object)
 {
     // HERE LIST<SIMPLEOBJECT> is always NULL 
 }

Any ideas what am I doing wrong here ?

Tieson T.
  • 20,774
  • 6
  • 77
  • 92
DevHelp
  • 305
  • 4
  • 21
  • 1
    A `partial` on its own will not work because you not adding indexers to the `name` attribute. Refer [this answer](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) for some options –  Oct 02 '16 at 22:19

2 Answers2

0

The first time you render the partial view you will have something like this:

<div>
       <input type="text" name="FirstName" maxlength="50" />
</div>   
<div>
       <input type="text" name="LasttName" maxlength="50" />
</div>

When you add more than one partial view to the page, at the end only 2 text boxes will be posted to the server because they all have the same name.

To fix this issue, you have to change your partial view to make the input boxes like an array, you can add a property to your model and set it from the action assuming you added a property called Index to your model, your code should look like this

@model SimpleObject
    <div>
        <input type="button" value="Button" name="btn" />
        <div>
            <div>
                @Html.TextBox("FirstName["+Model.Index+"]", new { @class = "", @maxlength = "50" })
            </div>
            <div>
               @Html.TextBox("LastName["+Model.Index+"]", new { @class = "", @maxlength = "50" })
            </div>

With each button submit, you increment the Index and render the view.

Another solution, is to remove the partial view and add the input boxes using JavaScript, you can use Knockout

have a look at this article that explains how to do it: http://knockoutjs.com/examples/grid.html

Haitham Shaddad
  • 4,336
  • 2
  • 14
  • 19
0

Here are the changes that I did to code posted in original question to bind list of SimpleObjects to ComplexObject.

@Html.Partial("_PartialView")

The class looks like this :

public class ComplexObject
{
   public int SomeProperty {get;set;}
   public List<SimpleObject> Objects {get;set;}
}

and the partialview starts with BeginCollectionItem

@model AZSolutions.Framework.Model.SimpleObject
@using (Html.BeginCollectionItem("Objects")) { 
...
}
DevHelp
  • 305
  • 4
  • 21