2012-12-23 13 views
8

これは初めてのC#/ MVCプロジェクトで、モデルにバインドする際に問題が発生しています。私は適用Phil Haack's Postを読んで、すべての私の部分的な意見にEditorForを使用しました。カスタムモデルバインダーが必要ですか?助けてくださいMVC C#ネストされたリストの自動モデルバインド

簡単に言えば、私はエントリのリストを含む週のリストを持っています。これらのエントリは、時間のリストが含まれている

処置:

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

モデル:

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; } 
} 

ビュー(インデックス)

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

ビュー(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) 
    } 

ビュー(HoursDisplay)

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

モデルが正しく、すべてのデータを表示し、次のようにポストされたフォームのデータ出力は次のとおりです。

[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 

私はインデックス権を得たと思ったが、現在は空Oneweekを取得アクションで私は間違って何をしていますか?いかなる援助も感謝します。 (いくつかの繰り返しとHTMLは削除されました)

答えて

7

あなたの接頭辞は間違っています。たとえば:

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

は次のようになります。

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

あなたは余分なドット(.)を持っています。リストを使用してバインドする場合は、正しい構文についてもう一度Phil Haack's articleを読んでください。

gethours.[0]の部分にも同じ問題があります。

私は標準エディタテンプレート規則を使用して、あなたをお勧めしますし、任意のforeach文を書いて、インデックスを扱う避けるだろう:

~/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

それはあなたに完全に感謝しました。私は、EditorForが実際どれだけ役に立つか分かりませんでした。その結果、ビューモデルははるかに単純です。非常に有用な知識。ありがとう+メリークリスマス – user1925048

+0

Entry.cshtmlのコードは何ですか? – Apollo

関連する問題