2016-03-04 26 views
2

我正在做一個由設計一個小衆籌網站組成的類實驗室。當用戶創建一個項目時,他會被要求爲他的項目提供多少級別的獎勵。如果此金額優於0,他將被重定向到獎勵/創建頁面。 「創建」視圖有一個根據用戶想要的層數生成的表單。ASP MVC:將動態生成的提交表單綁定到多個對象

問題是我不知道如何使用一個提交按鈕將「for」循環的每個實例鏈接到特定的「RewardViewModel」對象,以及如何將所有這些對象傳遞給「post」方法在控制器中。

這裏是控制器「獲得」的方法(我知道我可能會改變綁定到視圖模型):

public ActionResult Create(int projectid, int amountOfTiers) 
    { 
     ViewBag.AmountOfTiers = amountOfTiers; 
     ViewBag.ProjectTitle = (from p in context.Projects where p.ProjectId == projectid select p).FirstOrDefault().Title; 
     RewardViewModel model = new RewardViewModel { ProjectId = projectid }; 
     return View(model); 
    } 

,這裏是視圖:

@model CrowdFundMe.ViewModels.RewardViewModel 

@{ 
ViewBag.Title = "Create"; 
} 
<body> 
@section Login{ 
    @Html.Action("_Login", "User") 
} 
<h2>Create</h2> 
<p>You are adding rewards for the project @ViewBag.ProjectTitle</p> 
@using (Html.BeginForm("Create", "Reward", FormMethod.Post)) 
    { 
    var u = ViewBag.AmountOfTiers; 
    for (int i = 0; i < u; i++) 
    { 
     var tier = i+1; 
     @Html.HiddenFor(model => model.ProjectId) 

     @Html.LabelFor(model => model.Tier, "Tier")<br /> 
     @Html.TextBoxFor(model => model.Tier, new {@Value = tier, @readonly="readonly"}) 
     <br /> 
     <br /> 

     @Html.LabelFor(model => model.Title, "Title")<br /> 
     @Html.TextBoxFor(model => model.Title) 
     @Html.ValidationMessageFor(model => model.Title) 
     <br /> 
     <br /> 

     @Html.LabelFor(model => model.AmountOfItems, "Quantity available (leave blank if unlimited)")<br /> 
     @Html.TextBoxFor(model => model.AmountOfItems) 
     @Html.ValidationMessageFor(model => model.AmountOfItems) 
     <br /> 
     <br /> 

     @Html.LabelFor(model => model.Description, "Description")<br /> 
     @Html.EditorFor(model => model.Description) 
     @Html.ValidationMessageFor(model => model.Description) 
     <br /> 
     <br /> 
    } 

    <input type="submit" value="Create" /> 
    } 

回答

1

您希望創建RewardViewModel的集合,因此您視圖中的模型必須是集合。目前,您只傳遞RewardViewModel的一個實例,然後使用for循環生成具有重複name屬性(以及重複的id屬性無效的html)的多個表單控件。

更改GET方法返回一個集合

public ActionResult Create(int projectid, int amountOfTiers) 
{ 
    List<RewardViewModel> model = new List<RewardViewModel>(); 
    for(int i = 0; i < amountOfTiers; i++) 
    { 
     model.Add(new RewardViewModel { ProjectId = projectid }); 
    } 
    ViewBag.ProjectTitle = (from p in context.Projects where p.ProjectId == projectid select p).FirstOrDefault().Title; 
    return View(model); 
} 

和視圖

@model List<RewardViewModel> 
.... 
@using (Html.BeginForm("Create", "Reward", FormMethod.Post)) 
{ 
    for(int i = 0; i < Model.Count; i++) 
    { 
     @Html.HiddenFor(m => m[i].ProjectId) 

     @Html.LabelFor(m => m[i].Title) 
     @Html.TextBoxFor(m => m[i].Title) 
     @Html.ValidationMessageFor(m => m[i].Title) 
     .... 
    } 
    <input type="submit" value="Create" /> 
} 

這將正確地索引命名您的控件,並會張貼到

public ActionResult Create(List<RewardViewModel> model) 

方注意:刪除new { @Value = tier }(從不設置value屬性n使用HtmlHelper方法),並且它不清楚爲什麼你使Tier屬性readonly - 它的值沒有在控制器中設置,並且不能在視圖中更改,因此將它包括在視圖中似乎毫無意義。如果你想添加一個連續的數字到屬性,那麼在控制器中執行 - 例如model.Add(new RewardViewModel { ProjectId = projectid, Tier = i + 1 });

請注意,也不需要使用@Html.LabelFor(model => model.Tier, "Tier") - 如果顯示文本與屬性名稱匹配,則它可以僅爲@Html.LabelFor(model => model.Tier)

+0

它工作完美。感謝所有的細節。 要回答您自己關於我的代碼的問題,我設置了層級值並將其設置爲只讀,因爲用戶不應編輯他正在編碼的獎勵的層次級別。如果他選擇了2級獎勵,他必須具有「第1級」和「第2級」,並且不能編輯例如「第5級」和「第8級」中的獎勵。 – Morgoth

+0

只要確保您不要在視圖中設置'value'屬性。在將模型傳遞給視圖之前,將其設置在視圖中,正如我在第二個最後一段中指出的那樣 –

+0

我在創建控制器中的Create get方法中的每個新對象時添加了「Tier = i + 1」,而不是設置在視圖中的價值。再次感謝您的寶貴意見。 – Morgoth