2011-10-20 125 views
2

所有,請清除了我的困惑是如何模型結合與IEnumerables和編輯模板的作品。ASP.Net MVC3模型綁定的IEnumerable <T>與編輯模板

我有一個觀點,Approve.cshtml

@model IEnumerable<MvcWebsite.Models.Approve> 
<table> 
    <tr> 
     <th> 
      Name 
     </th> 
    </tr> 
    @Html.EditorForModel() 
</table> 

模型,Approve.cs

public class Approve 
{ 
    public string Name { get;set;} 
    public string Role { get; set; } 
} 

和編輯模板

@model MvcWebsite.Models.Approve 

@using (Html.BeginForm("Approve", "Registration", FormMethod.Post)) 
{ 
<tr> 
    <td> 
     @Html.HiddenFor(m => m.Name) 
     @Html.EditorFor(m => m.Role) 
    </td> 
    <td> 
     <input type="submit" value="Approve" class="submit-button" />    
    </td> 
</tr> 

}

這是一切都很好。它呈現以下輸出。

 <input name="[0].Name" type="hidden" value="" /> 
     .... 

但是,在我的控制器中,我似乎無法接收模型(綁定)的值。

[HttpPost] 
public ActionResult Approve(Approve approveModel) 
{ 
    .... approveModel has all default values 
} 

有人可以闡明我在做什麼錯在這裏?我縮寫代碼,我使用編輯器模板與我的模型中的其他EditorFor和HiddenFor字段...

編輯:我基本上有一個表佈局,每個用戶名,一個文本框,我可以輸入他們的角色(用戶或管理員),然後是提交給我的控制器的批准按鈕。因此,我只想返回一個Approve對象。我可以把整個的IEnumerable回到我的控制器,但如果我這樣做,我怎麼能知道哪個項目是一個我點擊批准按鈕(提交)呢?

編輯: 所以我已經修改了代碼,使我有我的周圍整個視圖Approve.cshtml

@model IEnumerable<MvcWebsite.Models.Approve> 
@using (Html.BeginForm("Approve", "Program", FormMethod.Post)) 
{ 
<table> 
    <tr> 
     <th> 
      Name 
     </th> 
    </tr> 
    @Html.EditorForModel() 
</table> 
} 

單一形式再變控制器

[HttpPost] 
public ActionResult Approve(IEnumerable<Approve> approvals) 
{ 
    // ??????????????????????? 
} 

現在的我米仍然不清楚如何知道我點擊批准的行。我知道有其他的方法來完成這項任務(創建批准複選框,並批准任何檢查等),但我需要點擊一個按鈕,只有1排回保存到數據庫的能力,無論如果用戶輸入信息放入其他行。它是更好的做法來包裝它自己的模型(即AllApprovals)我的IEnumerable內,然後輔助屬性添加到父模型(SelectedIndex的,等等)?如果這是要採取的方法,那麼在點擊批准按鈕後,如何設置SelectedIndex?這仍然是jQuery魔術還是有一個正確的MVC方式來實現這一點? jquery的魔法對我來說似乎很ha??

編輯:基於Brian的反應,這是我的最後。仍然感覺不太對,但它的工作原理!

查看

@model IEnumerable<MvcWebsite.Models.Approve> 
<table> 
    <tr> 
     <th> 
      Name 
     </th> 
    </tr> 
    @Html.EditorForModel() 
</table> 

編輯模板

@using (Html.BeginForm("Approve", "Registration", FormMethod.Post)) 
{ 
<tr> 
    <td> 
     @Html.HiddenFor(m => m.Name) 
     @Html.EditorFor(m => m.Role) 
    </td> 
    <td> 
     <input type="submit" value="Approve" class="submit-button" />    
    </td> 
</tr> 
} 

控制器

[HttpPost] 
public ActionResult Approve([Bind(Prefix="approval")]Approve approval) { 
    // WORKS! 
} 

回答

1

由於您一次只更換一個,我認爲以下方法比試圖找出控制器哪些值發生更改或添加更改的屬性並通過javascript進行設置要容易。

變化Approve.cshtml到

@model IEnumerable<MvcWebsite.Models.Approve> 
<table> 
    <tr> 
     <th colspan=2> 
      Name 
     </th> 
    </tr> 
@foreach(var user in Model){ 
    @using (Html.BeginForm("Approve", "Registration", FormMethod.Post))   { 
    <tr> 
     <td> 
      @Html.EditorFor(m => user) 
     </td> 
     <td> 
      <input type="submit" value="Approve" class="submit-button" />    
     </td> 
    </tr> 
    } 
} 
</table> 

更改Approve編輯模板,以

@Html.HiddenFor(m => m.Name) 
@Html.EditorFor(m => m.Role) 
+1

之間的映射。我將其標記爲正確答案,因爲它工作正常。然而,這是做到這一點的「正確」方式嗎?我在其他地方讀過,如果你在視圖中使用了Foreach,那麼你做錯了什麼。此外,我需要在我的控制器中使用綁定前綴來工作[綁定(前綴=「批准」)] – firetoast

+1

這聽起來像是適合你,現在。你從現在開始回過頭來看看代碼,提供更多關於你正在構建的系統的經驗和知識,並認爲「wtf是我的想法」。不用擔心它是否是「正確的」,但是完成任務也很好。正如所有事情一樣,適度是關鍵。 –

+0

偶然發現了這個問題,但是上面的內容並不正確,因爲它會產生無效的標記 - 除了​​(或th等),在表格中的任何位置放置表單元素都是無效的。它可能「工作」,但它很冒險。 – smdrager

0

你綁定到單獨審批類,你應該綁定到IEnumerable<Approve>

+0

跟進,如果我綁定到了IEnumerable ,我怎麼能知道哪些的形式發佈?我本質上是用它自己的形式來包裝每個Approve(EditorTemplate)。在該表單中,我有一個EditorFor字段,在其中輸入一個值(用戶或管理員),然後將每個行作爲自己的Approve模型提交給控制器。我猜測有更好的方法來做我想做的事.. – firetoast

+0

你不需要每行一個新的表單,只需在批准的模型上創建一個名爲id的屬性並使用@ Html.Hidden來渲染它。通過這種方式,您可以計算批准修改模型和新值 –

0

馬丁是正確的我只是想添加更多的信息。您使用[0]呈現的HTML是模型聯編程序查看的特殊語法,並且假定您正在使用列表(如果有對象)。由於您的操作方法只有一個Approve類而不是kist,因此您遇到此問題。