title: ASP.NET MVC 5 : Binding all the partial views to the main controller
body: <p>I am developing a web app using ASP.NET MVC 5. I have multiple partial views and their corresponding models, but only one controller corresponding to the main view, that uses below code to display each of the partial views.</p>
  
  <pre><code>@{Html.RenderPartial("PartialViewName");} 
  </code></pre>
  
  <p>My question is, how do I pass the form data from all the partial views (including the main view) to the main controller?</p>
  
  <p>Initially, when I added only 1 partial view, I added it's model as a parameter to the main controller's <code>public ActionResult Index(MainModelName model1, PartialModelName pmodel1)</code>. and that worked fine and I could access the data from the partial view in the main controller.</p>
  
  <p>But, when I added the 2nd partial view and updated the <code>public ActionResult Index(...)</code> with an additional partial model parameter, it didn't help, as in the data is not being passed from the partial view to the main controller. though I don't get any error.</p>
  
  <p>My main model class has the object references of the partial models as its data members. From what I read, I need to have a list of models as a parameter to the method in the main controller, but my models are not sub-types.</p>
  
  <p>What's the idiomatic way of handling such a situation?</p>
  
  <p>Thank you!</p>
  
  <p>EDIT1 : Here's the code for a sample app, I get null reference error while accessing <code>mainModel.PartialModel2.Pm2</code> in MainController.cs, while I can access <code>mainModel.PartialModel1.Pm1</code> properly.</p>
  
  <p><strong>MainModel.cs</strong></p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  
  namespace TestApp.Models
  {
      public class MainModel
      {
          private int mm1;
          private PartialModel1 partialModel1;
          private PartialModel2 partialModel2;
  
          public int Mm1 { get =&gt; mm1; set =&gt; mm1 = value; }
          public PartialModel1 PartialModel1 { get =&gt; partialModel1; set =&gt; partialModel1 = value; }
          public PartialModel2 PartialModel2 { get =&gt; partialModel2; set =&gt; partialModel2 = value; }
      }
  }
  </code></pre>
  
  <p><strong>PartialModel1.cs</strong></p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  
  namespace TestApp.Models
  {
      public class PartialModel1
      {
          private int pm1;
  
          public PartialModel1()
          {
          }
  
          public int Pm1 { get =&gt; pm1; set =&gt; pm1 = value; }
      }
  }
  </code></pre>
  
  <p><strong>PartialModel2.cs</strong></p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  
  namespace TestApp.Models
  {
      public class PartialModel2
      {
          private int pm2;
  
          public PartialModel2()
          {
          }
  
          public int Pm2 { get =&gt; pm2; set =&gt; pm2 = value; }
      }
  }
  </code></pre>
  
  <p><strong>Index.cshtml</strong></p>
  
  <pre><code>@model TestApp.Models.MainModel
  
  @{
      Layout = null;
  }
  
  &lt;!DOCTYPE html&gt;
  
  &lt;html&gt;
  &lt;head&gt;
      &lt;meta name="viewport" content="width=device-width" /&gt;
      &lt;title&gt;Index&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
      @using (Html.BeginForm())
      {
          @Html.AntiForgeryToken()
  
          &lt;div class="form-horizontal"&gt;
              &lt;h4&gt;MainModel&lt;/h4&gt;
              &lt;hr /&gt;
              @Html.ValidationSummary(true, "", new { @class = "text-danger" })
              &lt;div class="form-group"&gt;
                  @Html.LabelFor(model =&gt; model.Mm1, htmlAttributes: new { @class = "control-label col-md-2" })
                  &lt;div class="col-md-10"&gt;
                      @Html.EditorFor(model =&gt; model.Mm1, new { htmlAttributes = new { @class = "form-control" } })
                      @Html.ValidationMessageFor(model =&gt; model.Mm1, "", new { @class = "text-danger" })
                  &lt;/div&gt;
              &lt;/div&gt;
  
              &lt;div class="form-group"&gt;
                  @{ Html.RenderPartial("Partial1", Model);  }
                  @{ Html.RenderPartial("Partial2", Model);  }
              &lt;/div&gt;
  
              &lt;div class="form-group"&gt;
                  &lt;div class="col-md-offset-2 col-md-10"&gt;
                      &lt;input type="submit" value="Create" class="btn btn-default" /&gt;
                  &lt;/div&gt;
              &lt;/div&gt;
          &lt;/div&gt;
                      }
  
      @*&lt;div&gt;
              @Html.ActionLink("Back to List", "Index")
          &lt;/div&gt;*@
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p><strong>Partial1.cshtml</strong></p>
  
  <pre><code>@model TestApp.Models.MainModel
  
  @using (Html.BeginForm("MainModel")) 
  {
      @Html.AntiForgeryToken()
  
      &lt;div class="form-horizontal"&gt;
          &lt;h4&gt;PartialModel1&lt;/h4&gt;
          &lt;hr /&gt;
          @Html.ValidationSummary(true, "", new { @class = "text-danger" })
          &lt;div class="form-group"&gt;
              @Html.LabelFor(model =&gt; model.PartialModel1.Pm1, htmlAttributes: new { @class = "control-label col-md-2" })
              &lt;div class="col-md-10"&gt;
                  @Html.EditorFor(model =&gt; model.PartialModel1.Pm1, new { htmlAttributes = new { @class = "form-control" } })
                  @Html.ValidationMessageFor(model =&gt; model.PartialModel1.Pm1, "", new { @class = "text-danger" })
              &lt;/div&gt;
          &lt;/div&gt;
  
          @*&lt;div class="form-group"&gt;
              &lt;div class="col-md-offset-2 col-md-10"&gt;
                  &lt;input type="submit" value="Create" class="btn btn-default" /&gt;
              &lt;/div&gt;
          &lt;/div&gt;*@
      &lt;/div&gt;
  }
  
  @*&lt;div&gt;
      @Html.ActionLink("Back to List", "Index")
  &lt;/div&gt;*@
  </code></pre>
  
  <p><strong>Partial2.cshtml</strong></p>
  
  <pre><code>@model TestApp.Models.MainModel
  
  @using (Html.BeginForm("MainModel")) 
  {
      @Html.AntiForgeryToken()
  
      &lt;div class="form-horizontal"&gt;
          &lt;h4&gt;PartialModel2&lt;/h4&gt;
          &lt;hr /&gt;
          @Html.ValidationSummary(true, "", new { @class = "text-danger" })
          &lt;div class="form-group"&gt;
              @Html.LabelFor(model =&gt; model.PartialModel2.Pm2, htmlAttributes: new { @class = "control-label col-md-2" })
              &lt;div class="col-md-10"&gt;
                  @Html.EditorFor(model =&gt; model.PartialModel2.Pm2, new { htmlAttributes = new { @class = "form-control" } })
                  @Html.ValidationMessageFor(model =&gt; model.PartialModel2.Pm2, "", new { @class = "text-danger" })
              &lt;/div&gt;
          &lt;/div&gt;
  
          @*&lt;div class="form-group"&gt;
              &lt;div class="col-md-offset-2 col-md-10"&gt;
                  &lt;input type="submit" value="Create" class="btn btn-default" /&gt;
              &lt;/div&gt;
          &lt;/div&gt;*@
      &lt;/div&gt;
  }
  
  @*&lt;div&gt;
      @Html.ActionLink("Back to List", "Index")
  &lt;/div&gt;*@
  </code></pre>
  
  <p><strong>MainController.cs</strong></p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Web.Mvc;
  using TestApp.Models;
  
  namespace TestApp.Controllers
  {
      public class MainController : Controller
      {
          // GET: Main
  
          [HttpGet]
          public ActionResult Index()
          {
              return View();
          }
  
          [HttpPost]
          public ActionResult Index(MainModel mainModel)
          {
              //Access mainModel.PartialModel1.Pm1
              //Access mainModel.PartialModel2.Pm2 
  
              string msg = mainModel.PartialModel1.Pm1 + " " + mainModel.PartialModel2.Pm2;
              ViewBag.message = msg;
  
  
              return View("Success");
          }
      }
  }
  </code></pre>
  
  <p>EDIT 2: If I just keep it <code>@{ Html.RenderPartial("Partial2");  }</code>, I get this error - <code>The model item passed into the dictionary is of type 'TestApp.Models.Main', but this dictionary requires a model item of type 'TestApp.Models.Partial2'.</code></p>
  
  <p><strong>MainController.cs</strong></p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Web.Mvc;
  using TestApp.Models;
  
  namespace TestApp.Controllers
  {
      public class MainController : Controller
      {
          // GET: Main
  
          [HttpGet]
          public ActionResult Index()
          {
              return View(new Main() { Partial1 = new Partial1(), Partial2 = new Partial2() });
  
          }
  
          [HttpPost]
          public ActionResult Index(Main mainModel)
          {
              //Access mainModel.PartialModel1.Pm1
              //Access mainModel.PartialModel2.Pm2            
  
              string msg = mainModel.Partial1.Pm1 + " " + mainModel.Partial2.Pm2;
              ViewBag.message = msg;
  
              return View("Success");
          }
      }
  }
  </code></pre>
  
  <p><strong>Main.cs</strong></p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  
  namespace TestApp.Models
  {
      public class Main
      {
          public int Mm1 { get; set; }
          public Partial1 Partial1 { get; set; }
          public Partial2 Partial2 { get; set; }
      }
  }
  </code></pre>
  
  <p><strong>Partial1.cs</strong></p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  
  namespace TestApp.Models
  {
      public class Partial1
      {
          public Partial1()
          {
          }
          public int Pm1 { get; set; }
      }
  }
  </code></pre>
  
  <p><strong>Partial2.cs</strong></p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  
  namespace TestApp.Models
  {
      public class Partial2
      {
          public Partial2()
          {
          }
          public int Pm2 { get; set; }
      }
  }
  </code></pre>
  
  <p><strong>Index.cshtml</strong></p>
  
  <pre><code>@model TestApp.Models.Main
  
  @{
      Layout = null;
  }
  
  &lt;!DOCTYPE html&gt;
  
  &lt;html&gt;
  &lt;head&gt;
      &lt;meta name="viewport" content="width=device-width" /&gt;
      &lt;title&gt;Index&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
      @using (Html.BeginForm())
      {
          @Html.AntiForgeryToken()
  
          &lt;div class="form-horizontal"&gt;
              &lt;h4&gt;MainModel&lt;/h4&gt;
              &lt;hr /&gt;
              @Html.ValidationSummary(true, "", new { @class = "text-danger" })
              &lt;div class="form-group"&gt;
                  @Html.LabelFor(model =&gt; model.Mm1, htmlAttributes: new { @class = "control-label col-md-2" })
                  &lt;div class="col-md-10"&gt;
                      @Html.EditorFor(model =&gt; model.Mm1, new { htmlAttributes = new { @class = "form-control" } })
                      @Html.ValidationMessageFor(model =&gt; model.Mm1, "", new { @class = "text-danger" })
                  &lt;/div&gt;               
  
              &lt;/div&gt;
  
              @{ Html.RenderPartial("Partial2");  }
              @{ Html.RenderPartial("Partial1");  }
  
              &lt;div class="form-group"&gt;
                  &lt;div class="col-md-offset-2 col-md-10"&gt;
                      &lt;input type="submit" value="Create" class="btn btn-default" /&gt;
                  &lt;/div&gt;
              &lt;/div&gt;
          &lt;/div&gt;
                      }
  
      @*&lt;div&gt;
              @Html.ActionLink("Back to List", "Index")
          &lt;/div&gt;*@
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p><strong>Partial1.cshtml</strong></p>
  
  <pre><code>@model TestApp.Models.Partial1
  
  
  @Html.AntiForgeryToken()
  
  &lt;div class="form-horizontal"&gt;
      &lt;h4&gt;PartialModel1&lt;/h4&gt;
      &lt;hr /&gt;
      @Html.ValidationSummary(true, "", new { @class = "text-danger" })
      &lt;div class="form-group"&gt;
          @Html.LabelFor(model =&gt; model.Pm1, htmlAttributes: new { @class = "control-label col-md-2" })
          &lt;div class="col-md-10"&gt;
              @Html.EditorFor(model =&gt; model.Pm1, new { htmlAttributes = new { @class = "form-control" } })
              @Html.ValidationMessageFor(model =&gt; model.Pm1, "", new { @class = "text-danger" })
          &lt;/div&gt;
      &lt;/div&gt;
  
  
  &lt;/div&gt;
  
  
  @*&lt;div&gt;
          @Html.ActionLink("Back to List", "Index")
      &lt;/div&gt;*@
  </code></pre>
  
  <p><strong>Partial2.cshtml</strong></p>
  
  <pre><code>@model TestApp.Models.Partial2
  
  
  @Html.AntiForgeryToken()
  
  &lt;div class="form-horizontal"&gt;
      &lt;h4&gt;PartialModel2&lt;/h4&gt;
      &lt;hr /&gt;
      @Html.ValidationSummary(true, "", new { @class = "text-danger" })
      &lt;div class="form-group"&gt;
          @Html.LabelFor(model =&gt; model.Pm2, htmlAttributes: new { @class = "control-label col-md-2" })
          &lt;div class="col-md-10"&gt;
              @Html.EditorFor(model =&gt; model.Pm2, new { htmlAttributes = new { @class = "form-control" } })
              @Html.ValidationMessageFor(model =&gt; model.Pm2, "", new { @class = "text-danger" })
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  
  
  @*&lt;div&gt;
          @Html.ActionLink("Back to List", "Index")
      &lt;/div&gt;*@
  </code></pre>