2012-12-23 7 views
8

Dies ist mein erstes C#/MVC-Projekt und ich habe Probleme mit der Bindung an ein Modell. Ich habe eine angewandte Phil Haack's Post gelesen und EditorFor für alle meine Teilansichten verwendet. Brauche ich ein benutzerdefiniertes Model Binder? Bitte helfenMVC C# Automatische Modellbindung in verschachtelten Listen

Kurz gesagt, ich habe eine Liste von Wochen, die eine Liste von Einträgen enthalten. Diese Einträge enthalten eine Liste von Stunden

Aktion:

[HttpPost] 
public ActionResult SubmitRecords(List<WeekCollection> itemData) 
{ 
    //do stuff 
    return View(); 
} 

Modell:

public class WeekCollection 
{ 
    public WeekCollection() 
    { 
     this.OneWeek = new List<Entry>(); 
    } 

    public List<Entry> OneWeek { get; set; } 
} 

[Bind(Exclude = "Task, Project")] 
public class Entry 
{ 
    public int ProjectId { get; set; } 
    public virtual Projects Project { get; set; } 

    public int TaskId { get; set; } 
    public virtual Tasks Task { get; set; } 

    public bool Billable { get; set; } 
    public List<Hours> Gethours { get; set; } 
} 

public class Hours 
{ 
    public float NumberOfHours { get; set; } 
} 

Views (Index)

//within partial view iteration with incrementing u (u++) 
@using(@Html.BeginForm()) 
{ 
    @Html.EditorFor(m => m[u].OneWeek, "TimesheetWeek") 
    <input type="Submit"> 
} 

Views (TimesheetWeek)

@foreach (var value in Model) 
{ 
    v++; 
    if (Model.All(x => x.projectId == 0)) 
    { 
     @Html.DropDownListFor(p => p[v].projectId, (IEnumerable<SelectListItem>)projectList, "Select Project", new { @class = "notSelect" }) 
     @Html.DropDownListFor(t => t[v].taskId, (IEnumerable<SelectListItem>)taskList, "Select Task", new { @class = "notSelect" }) 
    } 
    else 
    { 
     if (value.projectId != 0) 
     {  
      @Html.DropDownListFor(p => p[v].projectId, (IEnumerable<SelectListItem>)projectList, new Dictionary<string, Object> { { "class", "SelectDrop" }, { "data-selectHead", value.projectId } }) 
      @Html.DropDownListFor(t => t[v].taskId, (IEnumerable<SelectListItem>)taskList, new Dictionary<string, Object> { { "class", "SelectDrop" }, { "data-selectHead", value.taskId } }) 
     } 
    } 

    @Html.CheckBoxFor(b => b[v].billable) 
    @Html.EditorFor(h => h[v].gethours, "HoursDisplay") 

    @value.gethours.Sum(a => a.numberOfHours) 
    } 

Ansicht (HoursDisplay)

@for (var i = 0; i < Model.Count(); i++) 
{ 
    @Html.TextBoxFor(m => m[i].numberOfHours) 
} 

Modell zeigt alle Daten korrekt und die Formulardaten Ausgabe geschrieben ist wie folgt:

[0].OneWeek.[0].projectId:1 
[0].OneWeek.[0].taskId:1 
[0].OneWeek.[0].billable:true 
[0].OneWeek.[0].billable:false 
[0].OneWeek.[0].gethours.[0].numberOfHours:0 
[0].OneWeek.[0].gethours.[1].numberOfHours:5 
[0].OneWeek.[0].gethours.[2].numberOfHours:7 
[0].OneWeek.[0].gethours.[3].numberOfHours:6 
[0].OneWeek.[0].gethours.[4].numberOfHours:4 
[0].OneWeek.[0].gethours.[5].numberOfHours:8 
[0].OneWeek.[0].gethours.[6].numberOfHours:0 

Ich dachte, ich die Indizierung richtig verstanden habe, aber zur Zeit eine leere einwöchige bekommen in der Aktion. Was mache ich falsch? Jede Hilfe wird geschätzt. (Einige Wiederholungen und HTML wurde entfernt)

Antwort

7

Ihre Präfixe sind falsch. Zum Beispiel:

[0].OneWeek.[0].projectId:1 

sollte sein:

[0].OneWeek[0].projectId:1 

Sie haben einen zusätzlichen Punkt (.). Lesen Sie erneut Phil Haack's article für die korrekte Syntax beim Binden mit Listen.

Sie haben das gleiche Problem mit dem gethours.[0] Teil.

Ich würde Ihnen empfehlen, die Standard-Editor Vorlagen Konventionen und vermeiden Sie foreach-Schleifen zu schreiben und den Umgang mit Indizes:

~/Views/Home/Index.cshtml:

@model List<WeekCollection> 
@using(Html.BeginForm()) 
{ 
    @Html.EditorForModel() 
    <input type="Submit" /> 
} 

~/Views/Home/EditorTemplates/WeekCollection.cshtml:

@model WeekCollection 
@Html.EditorFor(x => x.OneWeek) 

~/Views/Home/EditorTemplates/Entry.cshtml:

@model Entry 
... 
+0

Das hat perfekt funktioniert danke. Ich habe nicht erkannt, wie nützlich der EditorFor wirklich ist, und als Ergebnis sind die Ansichtsmodelle viel einfacher. Sehr nützliches Wissen. Danke + Frohe Weihnachten – user1925048

+0

Was ist der Code für Entry.cshtml? – Apollo

Verwandte Themen