Search code examples
ajaxasp.net-mvcmodel-view-controllerasp.net-mvc-viewmodel

Does ViewModel supports Nested Models ? Can Virtual property can be applied to viewModel?


I am using .net 4.5.1, visual studio 2013. I have created a invoice create page with ViewModel -CreateInvoiceViewModel.

public class CreateInvoiceViewModel
{
    public int EntityID { get; set; }
    .
    .
    public ICollection<InvoicePartialCreateMainBillViewModel> MainBill { get; set; }

    public ICollection<InvoicePartialCreateDetailBillViewModel> DetailBill { get; set; }
}

On clicking "Generate Invoice", through AJAX, a partial view page will be loaded in the same page with ViewModel which are nested with two more View Models. The nested View Models are given data in the AJAX called function. partial View page ViewModel - InvoicePartialCreateViewModel

public class InvoicePartialCreateViewModel
{
    public InvoicePartialCreateViewModel()
    {
        this.MainBill = new HashSet<InvoicePartialCreateMainBillViewModel>();
        this.DetailBill = new HashSet<InvoicePartialCreateDetailBillViewModel>();
    }
    public float TotalAmount { get; set; }
    .
    .
    public ICollection<InvoicePartialCreateMainBillViewModel> MainBill { get; set; }

    public ICollection<InvoicePartialCreateDetailBillViewModel> DetailBill { get; set; }

    internal void CreateMainBill(int count)
    {
        for(int i = 0; i < count; i++)
        {
            this.MainBill.Add(new InvoicePartialCreateMainBillViewModel());
        }
    }
    internal void CreateDetailBill(int count)
    {
        for (int i = 0; i < count; i++)
        {
            this.DetailBill.Add(new InvoicePartialCreateDetailBillViewModel());
        }
    }
}

The Nested Models - InvoicePartialCreateMainBillViewModel, InvoicePartialCreateDetailBillViewModel

public class InvoicePartialCreateMainBillViewModel
{
    public string PackageName { get; set; }
    .
    .
    public virtual InvoicePartialCreateViewModel InvoiceCreate { get; set; }
}

public class InvoicePartialCreateDetailBillViewModel
{
    public DateTime OrderDate { get; set; }
    .
    .
    public virtual InvoicePartialCreateViewModel InvoiceCreate { get; set; }
}

The Nested Models are called by html helper @Html.EditorFor

@Html.EditorFor(model => model.MainBill)
@Html.EditorFor(model => model.DetailBill)

The partial view renders partially. The Nested Models are not rendering. Does ViewModel supports Nested Models and can Virtual property can be applied to viewModel


Solution

    1. Viewmodel does support nested models.

    2. Although it is not recommended to use virtual in ViewModel.

      public class CreateInvoiceViewModel { public int EntityID { get; set; }

      public IList<InvoicePartialCreateMainBillViewModel> MainBill { get; set; }
      
      public IList<InvoicePartialCreateDetailBillViewModel> DetailBill { get; set; }
      

      }

      Virtual is usually used with domain objects, which are ultimately used to populate or map the viewmodels.

      Although, it may completely depend on your scenario.

      Example, you have a base class with property A, and a derived class 1 and derived class 2. Both need property A, but they have their own implementation. Then you can keep property A as virtual and override in either of the derived classes as per the requirement.

      Ex:

      public class BaseViewModel
      {           
         [Required]
         public virtual int propA { get; set;}           
      }
      
      public class DerivedViewModel1
      {
          ......
      }
      
      public class DerivedViewMode2
      {     
          public override int propA { get; set; }
      }
      

      In such a scenario you can use virtual, else not recommended.