MVC 3 Nested EditorFor Templates
        Posted  
        
            by 
                Gordon Hickley
            
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Gordon Hickley
        
        
        
        Published on 2012-10-31T09:37:26Z
        Indexed on 
            2012/11/01
            5:01 UTC
        
        
        Read the original article
        Hit count: 240
        
I am working with MVC 3, Razor views and EditorFor templates.
I have three simple nested models:-
public class BillingMatrixViewModel
{
    public ICollection<BillingRateRowViewModel> BillingRateRows { get; set; }
    public BillingMatrixViewModel()
    {
        BillingRateRows = new Collection<BillingRateRowViewModel>();
    }
}
public class BillingRateRowViewModel
{
    public ICollection<BillingRate> BillingRates { get; set; }
    public BillingRateRowViewModel()
    {
        BillingRates = new Collection<BillingRate>();
    }
}
public class BillingRate
{   
  public int Id { get; set; }
  public int Rate { get; set; } 
}
The BillingMatrixViewModel has a view:-
@using System.Collections
@using WIP_Data_Migration.Models.ViewModels
@model WIP_Data_Migration.Models.ViewModels.BillingMatrixViewModel
<table class="matrix" id="matrix">      
    <tbody>
        <tr>
           @Html.EditorFor(model => Model.BillingRateRows, "BillingRateRow")    
        </tr>
    </tbody>
</table>
The BillingRateRow has an Editor Template called BillingRateRow:-
@using System.Collections
@model IEnumerable<WIP_Data_Migration.Models.ViewModels.BillingRateRowViewModel> 
@foreach (var item in Model)
{
    <tr>
        <td>
    @item.BillingRates.First().LabourClass.Name
    </td>
    @Html.EditorFor(m => item.BillingRates)
</tr>
}
The BillingRate has an Editor Template:-
@model WIP_Data_Migration.Models.BillingRate
<td>
  @Html.TextBoxFor(model => model.Rate,
                new {style = "width: 20px"})
</td>
The markup produced for each input is:-
<input name="BillingMatrix.BillingRateRows.item.BillingRates[0].Rate"    id="BillingMatrix_BillingRateRows_item_BillingRates_0__Rate" style="width: 20px;" type="text" value="0"/>
Notice the name and ID attributes the BillingRate indexes are handled nicely but the BillingRateRows has no index instead '.item.'. From my reasearch this is because the context has been pulled out due to the foreach loop, the loop shouldn't be necessary.
I want to achieve:-
<input name="BillingMatrix.BillingRateRows[0].BillingRates[0].Rate" id="BillingMatrix_BillingRateRows_0_BillingRates_0__Rate" style="width: 20px;" type="text" value="0"/>
If I change the BillingRateRow View to:-
@model WIP_Data_Migration.Models.ViewModels.BillingRateRowViewModel
<tr>
    @Html.EditorFor(m => Model.BillingRates)
</tr>
It will throw an InvalidOperationException, 'model item passed into the dictionary is of type System.Collections.ObjectModel.Collection [BillingRateRowViewModel] but this dictionary required a type of BillingRateRowViewModel.
Can anyone shed any light on this?
© Stack Overflow or respective owner