2016-07-05 23 views
0

我有下面的類定義爲我的ViewModel顯示對象的列表並設置值字段爲每個輸入MVC

public class CreateApplicationViewModel 
    { 
     public Step1ViewModel Step1 { get; set; } 
     public Step2StandAloneViewModel Step2StandAlone { get; set; } 
     public Step2ChildViewModel Step2Child { get; set; } 
     public Step3ViewModel Step3 { get; set; } 
     public Step4ViewModel Step4 { get; set; } 
    } 

我想其中包括以下的Step4ViewModel顯示項目:

public class Step4ViewModel 
    { 
     public List<DataDetails> DataDetails = new List<DataDetails>(); 

    } 

public class DataDetails 
    { 
     public string GroupCode { get; set; } 
     public string GroupDesc { get; set; } 
     public decimal DetailSequence { get; set; } 
     public string DetailCode { get; set; } 
     public string DetailDesc { get; set; } 
     public string YesNoFlag { get; set; } 
     public string NumberFlag { get; set; } 
     public string ValueFlag { get; set; } 
     public string DateFlag { get; set; } 
     public string ListValuesFlag { get; set; } 
     public string CommentFlag { get; set; } 
     public string CalcRateFlag { get; set; } 
     public string ColumnSequence { get; set; } 
     public string TextFlag { get; set; } 
     public string CheckboxFlag { get; set; } 
     public string YesNoValue { get; set; } 
     public int NumberValue { get; set; } 
     public DateTime DateValue { get; set; } 
     public string ListValue { get; set; } 
     public string CommentValue { get; set; } 
     public string TextValue { get; set; } 
     public bool CheckboxValue { get; set; } 
    } 

在我控制我填充Step4ViewModel.DataDetails像這樣:

private Step4ViewModel GetCaseDataDetails(string caseType) 
     { 
      Step4ViewModel model = new Step4ViewModel(); 

      List<DataDetails> data = new List<DataDetails>(); 
      List<DataDetailsValues> values = new List<DataDetailsValues>(); 

      var dataDetails = (from tb1 in db.DEFAULT_CASE_DATA_VW 
           join tb2 in db.CASE_DATA_DETAIL on tb1.CASE_DATA_GROUP_ID equals tb2.CASE_DATA_GROUP_ID 
           where tb1.BUS_CASE_CODE == caseType 
           orderby tb2.DETAIL_SEQUENCE 
           select new { tb1, tb2 }); 


      foreach (var detail in dataDetails.ToList()) 
      { 
       DataDetails i = new DataDetails(); 
       DataDetailsValues j = new DataDetailsValues(); 
       i.CalcRateFlag = detail.tb2.CALC_RATE_FLAG; 
       i.CheckboxFlag = detail.tb2.CHECKBOX_FLAG; 
       i.ColumnSequence = detail.tb2.COLUMN_SEQUENCE; 
       i.CommentFlag = detail.tb2.COMMENT_FLAG; 
       i.DateFlag = detail.tb2.DATE_FLAG; 
       i.DetailCode = detail.tb2.DETAIL_CODE; 
       i.DetailDesc = detail.tb2.DETAIL_DESC; 
       i.DetailSequence = detail.tb2.DETAIL_SEQUENCE; 
       i.GroupCode = detail.tb1.GROUP_CODE; 
       i.GroupDesc = detail.tb1.GROUP_DESC; 
       i.ListValuesFlag = detail.tb2.LIST_VALUES_FLAG; 
       i.NumberFlag = detail.tb2.NUMBER_FLAG; 
       i.TextFlag = detail.tb2.TEXT_FLAG; 
       i.ValueFlag = detail.tb2.VALUE_FLAG; 
       i.YesNoFlag = detail.tb2.YES_NO_FLAG; 
       data.Add(i); 
      } 
      model.DataDetails = data; 
      return model; 
     } 

我的你使用Step4ViewModel的ght過程是,對於每個DataDetail,我將顯示DetailDesc作爲標籤,然後在旁邊輸入NumberValue,YesOrNoValue,NumberValue,DateValue,ListValue,CommentValue,TextValue或CheckboxValue,具體取決於控件鍵入,然後將該數據發佈到服務器。我能夠成功顯示每個DataDetail.DetailDesc,但對於每個輸入(也會呈現),我輸入到輸入的值都不會回發到服務器。這是我的看法是什麼樣子:

@model Portal.Models.ViewModel.CreateApplicationViewModel 
@{ 
    ViewBag.Title = "Step 4/5"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 
@using System.Linq 

<h4>Case Data Details</h4> 

@using (Html.BeginForm("Step4", "CreateApplication", FormMethod.Post, new { @class = "col-sm-12" })) 
{ 

    foreach (var group in Model.Step4.DataDetails.GroupBy(item => item.GroupDesc)) 
    { 
     <div class="panel panel-primary"> 
      <div class="panel-heading">@Html.Encode(group.Key)</div> 
      <div class="panel-body"> 

       @for (var i = 0; i < group.Count(); i++) 
       { 
        <div class="form-group"> 
         <div class="row"> 
          <div class="col-xs-6"> 
           <label class="form-label">@Model.Step4.DataDetails[i].DetailDesc</label> 
          </div> 
          <div class="col-xs-6"> 
           @if (Model.Step4.DataDetails[i].TextFlag == "Y") 
           { 
            @Html.TextBoxFor(val => Model.Step4.DataDetails[i].TextValue, new { @class = "form-control" }) 
           } 
           else if (Model.Step4.DataDetails[i].CheckboxFlag == "Y") 
           { 
            @Html.CheckBoxFor(val => Model.Step4.DataDetails[i].CheckboxValue, new { @class = "checkbox" }) 
           } 
          </div> 
         </div> 
        </div> 
       } 
      </div> 
     </div> 
    } 
    <div class="col-sm-12"> 
     <div class="row"> 
      @Html.ActionLink("Cancel", "Welcome", "Home", null, new { @class = "btn btn-default" }) 
      <button class="btn btn-default" onclick="history.go(-1);">Previous</button> 
      <button type="submit" class="btn btn-default">Next</button> 
     </div> 
    </div> 

控制裝置,其後期數據

[HttpPost] 
public ActionResult Step4(Step4ViewModel step4) 
{ 
    if (ModelState.IsValid) 
    { 
     CreateApplicationViewModel model = (CreateApplicationViewModel)Session["case"]; 
     // model.Step4 = step4; 
     Session["case"] = model; 
     return View(); 
    } 
    return View(); 
} 

我想這可能是由於分組,這是我做的每一組分成單獨的HTML面板元件,但我的輸入是使用名稱中的索引號進行呈現。任何幫助或建議更好的方式來完成這將不勝感激。乾杯!

UPDATE

這是我更新的帖子控制器和視圖:

@model Portal.Models.ViewModel.CreateApplicationViewModel 
@{ 
    ViewBag.Title = "Step 4/5"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 
@using System.Linq 

<h4>Case Data Details</h4> 

@using (Html.BeginForm("Step4", "CreateApplication", FormMethod.Post, new { @class = "col-sm-12" })) 
{ 

    int index = 0; 
    foreach (var group in Model.Step4.DataDetails.GroupBy(item => item.GroupDesc)) 
    { 
     <div class="panel panel-primary"> 
      <div class="panel-heading">@Html.Encode(group.Key)</div> 
      <div class="panel-body"> 

       <input type="hidden" name="Step4.DataDetails.Index" value="@index" /> 

       @for (var i = 0; i < group.Count(); i++) 
       { 
        <div class="form-group"> 
         <div class="row"> 
          <div class="col-xs-6"> 
           <label class="form-label">@Model.Step4.DataDetails[i].DetailDesc</label> 
          </div> 
          <div class="col-xs-6"> 
           @if (Model.Step4.DataDetails[i].TextFlag == "Y") 
           { 
            @Html.TextBoxFor(val => val.Step4.DataDetails[i].TextValue, new { @class = "form-control" }) 
           } 
           else if (Model.Step4.DataDetails[i].CheckboxFlag == "Y") 
           { 
            @Html.CheckBoxFor(val => val.Step4.DataDetails[i].CheckboxValue, new { @class = "checkbox" }) 
           } 
          </div> 
         </div> 
        </div> 
       } 
      </div> 
     </div> 
     index++; 
    } 
    <div class="col-sm-12"> 
     <div class="row"> 
      @Html.ActionLink("Cancel", "Welcome", "Home", null, new { @class = "btn btn-default" }) 
      <button class="btn btn-default" onclick="history.go(-1);">Previous</button> 
      <button type="submit" class="btn btn-default">Next</button> 
     </div> 
    </div> 
} 


[HttpPost] 
     public ActionResult Step4(CreateApplicationViewModel step4) 
     { 
      if (ModelState.IsValid) 
      { 
       CreateApplicationViewModel model = (CreateApplicationViewModel)Session["case"]; 
       // model.Step4 = step4; 
       Session["case"] = model; 
       return View(); 
      } 
      return View(); 
     } 

更新2

我能夠得到的形式輸入,如果我傳遞的FormCollection到HttpPost控制器。任何想法,爲什麼我可以將這些值作爲FormCollection而不是模型?

回答

0

我能夠在我看來,以使用索引整數的想法,並從上面的答案遞增,並執行的想法以不同的方式來獲取模型回控制器:

@model Portal.Models.ViewModel.CreateApplicationViewModel 
@{ 
    ViewBag.Title = "Step 4/5"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 
@using System.Linq 

<h4>Case Data Details</h4> 

@using (Html.BeginForm("Step4", "CreateApplication", FormMethod.Post, new { @class = "col-sm-12" })) 
{ 
    int index = 0; 
    foreach (var group in Model.Step4.DataDetails.GroupBy(item => item.GroupDesc)) 
    { 

     <div class="panel panel-primary"> 
      <div class="panel-heading">@Html.Encode(group.Key)</div> 
      <div class="panel-body"> 
       @for (var i = 0; i < group.Count(); i++) 
       { 
        <div class="form-group"> 
         <div class="row"> 
          <div class="col-xs-6"> 
           <label class="form-label">@Model.Step4.DataDetails[i].DetailDesc</label> 
          </div> 
          <div class="col-xs-6"> 
           @Html.TextBoxFor(val => val.Step4.DataDetails[index].TextValue) 
           @Html.HiddenFor(val => val.Step4.DataDetails[index].GroupCode) 
          </div> 
         </div> 
        </div> 
        index++; 
       } 

      </div> 
     </div> 
    } 
    <div class="col-sm-12"> 
     <div class="row"> 
      @Html.ActionLink("Cancel", "Welcome", "Home", null, new { @class = "btn btn-default" }) 
      <button class="btn btn-default" onclick="history.go(-1);">Previous</button> 
      <button type="submit" class="btn btn-default">Next</button> 
     </div> 
    </div> 
} 

上面的代碼在視圖中給了我每個元素的正確索引,並允許我發帖

0

您正在發佈複雜對象列表。但是MVC DefaultModelBinder無法綁定到您的DataDetails對象,因爲在將表單與複雜對象列表發佈時,索引必須按順序排列。在你的情況下,由於嵌套for循環,這個序列被打破。所以你可以做的是採取一個單獨的變量,並使用默認的0值初始化 - 我試圖修改你的代碼。

@using (Html.BeginForm("Step4", "CreateApplication", FormMethod.Post, new { @class = "col-sm-12" })) 
{ 

    int index = 0; 
    foreach (var group in Model.Step4.DataDetails.GroupBy(item => item.GroupDesc)) 
    { 
     <div class="panel panel-primary"> 
      <div class="panel-heading">@Html.Encode(group.Key)</div> 
      <div class="panel-body"> 

       <input type="hidden" name="Step4.DataDetails.Index" value="@index" /> 

       @for (var i = 0; i < group.Count(); i++) 
       { 
        <div class="form-group"> 
         <div class="row"> 
          <div class="col-xs-6"> 
           <label class="form-label">@Model.Step4.DataDetails[i].DetailDesc</label> 
          </div> 
          <div class="col-xs-6"> 
           @if (Model.Step4.DataDetails[i].TextFlag == "Y") 
           { 
            @Html.TextBoxFor(val => val.Step4.DataDetails[i].TextValue, new { @class = "form-control" }) 
           } 
           else if (Model.Step4.DataDetails[i].CheckboxFlag == "Y") 
           { 
            @Html.CheckBoxFor(val => val.Step4.DataDetails[i].CheckboxValue, new { @class = "checkbox" }) 
           } 
          </div> 
         </div> 
        </div> 
       } 
      </div> 
     </div> 
     index++; 
    } 
    <div class="col-sm-12"> 
     <div class="row"> 
      @Html.ActionLink("Cancel", "Welcome", "Home", null, new { @class = "btn btn-default" }) 
      <button class="btn btn-default" onclick="history.go(-1);">Previous</button> 
      <button type="submit" class="btn btn-default">Next</button> 
     </div> 
    </div> 
} 

看看我在視圖中添加的隱藏字段。即使破壞了序列,也可以發佈數據。希望這對你有所幫助。

+0

首先,感謝您的回覆。我嘗試了上面的代碼,並且在回發到服務器時,我的模型的計數仍然爲0。這是我的柱控制器: '[HttpPost] 公共的ActionResult步驟4(Step4ViewModel步驟4) { 如果(ModelState.IsValid) { CreateApplicationViewModel模型=(CreateApplicationViewModel)會話[ 「殼體」]; // model.Step4 = step4; Session [「case」] = model; return View(); } return View(); }' – ghoston3rd

+0

我試圖將列表呈現給沒有嵌套for的視圖,但模型仍然不會發布到服務器。 – ghoston3rd

+0

@ ghoston3rd:在你的'Step4'動作方法中,將你的參數從'Step4ViewModel'改爲傳遞整個模型 - 'CreateApplicationViewModel'。所以發佈這個模型,而不是'Step4ViewModel'。 Mvc根據您的渲染控件名稱將數據發佈到控制器。因此,根據模型名稱,您的代碼 - 「@ Html.TextBoxFor(val => val.Step4.DataDetails [i] .TextValue,new {@class =」form-control「})''呈現。 –