問題出現在生成視圖時爲每個項目生成的名稱。模型聯編程序使用名稱 - 值對來計算如何將表單值映射到您期望的視圖模型中控制器。
當你使用@Html.HiddenFor(m=>m[i].Id)
,那是個好人,會產生在你的HTML下面的名稱屬性:
name="[0].ModelId"
以後的人會
name="[5].ModelId"
等等。
這裏是被你的看法產生什麼樣的HTML:
有兩個問題在這裏:
- 「選擇」出現在名字前面的值
- 這是使用兩次數組索引
這是因爲所有HTML標籤在最後工作的方式(HiddenFor,TextboxFor等)。他們根據lambda表達式確定name屬性 - 因爲您在第一個中使用的是m => m[0].ModelId
,所以它使用[0].ModelId
作爲名稱。在第二個,你用m=> selection[0].ModelId
,於是就用selection[i].ModelId
(它消除你作爲你的拉姆達的一部分,任何變量。
那麼,你如何解決這個問題?
您可以通過以下兩種方法之一來解決這在給定當前設置的情況下,你可以在循環外部使用一個計數器並將其用作數組索引,或者你可以利用額外的隱藏字段作爲索引字段。對於任何一種方法,你都必須放棄強類型的HiddenFor/TextBoxFor並使用Hidden/TextBox來代替,因此您可以手動設置正在生成的HTML元素的名稱。
與索引字段會發生什麼事是你有你的項目名稱爲類似如下:
<input type="hidden" name="Index" value="Model1"/>
<input type="hidden" name="[Model1].ModelId" value="1"/>
<input type="hidden" name="[Model1].ModelValue" value="Some value"/>
在第一次輸入的標籤,我把它叫做索引並設置一些值將作爲該指數這個相關的一組值。在剩餘的那些上,我使用第一個值中的值作爲數組索引,然後是該屬性的名稱。如果您處於從列表中添加/刪除項目的情況,並且無法保證在回發時依次包含所有數字,則此方法尤其有用。
因此,這是你的剃鬚刀的代碼可能是什麼樣子:
for (int i = 0; i < selection.Count(); i++) {
@Html.Hidden("Index", "Model"+selection[i].ModelId)
@Html.Hidden("[Model"+selection[i].ModelId + "].ModelId", selection[i].ModelId)
@Html.Hidden("[Model"+selection[i].ModelId + "].CreateDate", selection[i].CreateDate)
@Html.Hidden("[Model"+selection[i].ModelId + "].ModelValue", selection[i].ModelValue)
一點題外話,我選擇了包括單詞「模型」作爲索引的一部分,所以這樣它肯定知道,它指的是它作爲一個字典式的入口而不是數組中的數字位置。我不知道你是否絕對需要這樣做,我其實沒有嘗試過其他方式。我使用ModelId作爲索引值,因爲它應該是唯一的值。
最終的結果是,你應該已經生成的HTML看起來像這樣(在名稱方面的屬性):
希望幫助!
什麼視圖模型看起來像你想綁定到(在接收提交的控制器方法中)?它只是一個集合,你只是試圖返回原始集合的一個子集? – CorrugatedAir
我的視圖模型只是一個簡單的POCO類的集合。然後我的視圖可以編輯集合中的項目。所以,我不想減少原始收藏。子集「選擇」僅用於迭代我的集合中每個組的子集項。 –
我對這些物品的命名更感興趣,但我可能已經有足夠的空間去這裏了 – CorrugatedAir