0

There is main RegisterModel calling nested HomeAddress and MailAddress model.

public class RegisterModel
{
   Public string FirstName {get; set;}
   Public string LastName  {get; set;}
   Public HomeAddressModel homeAddress {get; set;}
   Public MailAddressModel mailAddress {get; set;}
}

public class HomeAddressModel
{
    Public string Street1 {get; set;}
    Public string Street2  {get; set;}
    Public string State {get; set;}
    Public string City {get; set;}
}

public class MailAddressModel
{
    Public string Street1 {get; set;}
    Public string Street2  {get; set;}
    Public string State {get; set;}
    Public string City {get; set;}
}

The Partial View for Address

@model MyNamespace.Models.???
@{
    Layout = "~/Views/_Layout.cshtml";
}
 <div id="Address">
   //Street1
   //Street2
   //State
   //City
 </div>

How will i define my Parital view so that I can bind it at runtime either with HomeAddressModel or MailAddressModel.

My main Register View

@model MyNamespace.Models.RegisterModel
@{
     Layout = "~/Views/_Layout.cshtml";
 }
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm" }))
{
  <div id="form">
    @Html.TextBoxFor("FirstName");
    @Html.TextBoxFor("LastName");
   //Render Partial View for HomeAddress.
   //Will provide a checkbox if Mailing Address is different.
   //Render Partial View for MailAddress.
  </div>
}

public ActionResult Register()
{  
    var model = new RegsiterModel();
    return View(model);
}

[HttpPost]
public ActionResult Register(RegisterModel model, 
                            HomeAddressModel  homeAddress, 
                            MailAddressModel mailingAddress)
{
       //Do Something with different Addresses
       return View();
}

There are 5 parts to this question : -

  1. Is the RegisterModel Class created correctly ? This is they way we can nest them ?
  2. Should we have single class for Address and 2 different Properties for both Addresses ? somethign like Address home {get;set;} and Address mail{get;set;}. if yes then how to achieve next things.
  3. How to create partial view for Address ? in both scenarios that is using separate HomeAddres class and MailAddress class. OR using single Address class.
  4. How to declare partialView in Main Register View with both approach as described above.
  5. How to make sure that in [HttpPost] Action Method we can read all values i.e. RegisterModel Values is binded, and individual addresses are also binded.
user2232861
  • 273
  • 2
  • 10
  • 27
  • Is it necessary to have 2 different models for addresses? – Necros May 06 '13 at 16:47
  • @Necros If we use one class then doesn't it make more complex? I tried using one but it messes up more for me especially in the [HttpPost] Action method how I would get 2 different addresses ? May be I don't know how to achieve using single Address class. – user2232861 May 06 '13 at 16:53

1 Answers1

1

Have a single model for address like

public class AddressModel
{
    Public string Street1 {get; set;}
    Public string Street2  {get; set;}
    Public string State {get; set;}
    Public string City {get; set;}
}

Make a partial view for it in Views/Shared/EditorTemplates/AddressModel.cshtml

@model MyNamespace.Models.AddressModel
<div id="Address">
   Html.TextBoxFor(m => m.Street1)
   //Street2
   //State
   //City
</div>

Now if you have your view model

public class RegisterModel
{
   Public string FirstName {get; set;}
   Public string LastName  {get; set;}
   Public AddressModel HomeAddress {get; set;}
   Public AddressModel MailAddress {get; set;}
}

Simply render partial views for each address like this

<div id="form">
    @Html.TextBoxFor(m => m.FirstName);
    @Html.TextBoxFor(m => m.LastName);
    @Html.EditorFor(m => m.HomeAddress) // !! -> this will render AdressModel.cshtml as a partial view, and will pass HomeAdress to it
   //Will provide a checkbox if Mailing Address is different.
    @Html.EditorFor(m => m.MailAddress)
</div>

Optionally you can wrap the call to EditorFor to your own helper method if you need more logic (additional parameters for the view or something like that)

In HttpPost method use this

[HttpPost]
public ActionResult Register(RegisterModel model)
{
}

and the addresses will bind to properties of RegisterModel.

Necros
  • 3,004
  • 23
  • 29
  • I tried above approach before.There are couple of problems e first is I don't want to use EditorFor as I want custom layout for each fields in address by making it a PartialView and second thing is the nested classes are not binded in [HttpPost] action method. I would have to use @html.Action("AdddressAction") and then instantiate the AddressModel in that action method and then explicitly pass the different Nested Models in [HttpPost] paramters. CHekc this out : - http://stackoverflow.com/questions/16344503/single-strongly-typed-partial-view-for-two-similar-classes-of-different-types – user2232861 May 06 '13 at 17:12
  • 1
    1. you define the layout of the partial view. Put it in the Views/Shared/EditorTemplates folder and name it the same as the view model (AdressModel.cshtml) - ill update my answer with this 2. Nested classes ARE binded in http post, as long as they are correctly named (ie.: input with name HomeAdress.Street1) - you achieve this by using EditorFor. – Necros May 06 '13 at 17:23