2017-01-16 71 views
2

我在mvc 5中編寫我的第一個生產應用程序。我試圖將自定義對象作爲參數傳遞給http post動作在我的控制器中。基本上,我有一個包裹在我的CustomerReport視圖模型中的視圖,因爲我有一個部分創建了一個模型,可以選擇從模型中選擇項目,我想通過控制器操作保存選擇以傳遞視圖模型(或視圖模型的屬性)作爲參數。如何將自定義模型對象從剃刀視圖傳遞給ASP.NET MVC中的控制器動作5

我的報告視圖模型

public class CustomerReport 
{ 
    public User User { get; set; } 
    public List<NewEnterprise> Enterprises { get; set; } 
    public NewEnterpriseRepository EnterpriseRepository { get; set; } 
    public NewCustomerRepository CustomerRepository { get; set; } 
    public NewProgramRepository ProgramRepository { get; set; } 
    public List<NewCustomer> Customers { get; set; } 
    public List<NewProgram> Programs { get; set; } 
    public List<InvoiceItem> InvoiceItems { get; set; } 
    public List<ReportSelectionItem> ReportSelectionItems { get; set; } 
    public List<ReportSelectionItem> FilteredSelectionItems { get; set; } 
    public DateTime StartDate { get; set; } 
    public DateTime EndDate { get; set; } 
    public string Start { get; set; } 
    public string End { get; set; } 
    public string ReportType { get; set; } 
    public NewReports Reports { get; set; } 

    public CustomerReport() 
    { 
     User = HttpContext.Current.GetUser(); 
     Enterprises = new List<NewEnterprise>(); 
     Customers = new List<NewCustomer>(); 
     Programs = new List<NewProgram>(); 
     InvoiceItems = new List<InvoiceItem>(); 
     ReportSelectionItems = new List<ReportSelectionItem>(); 
    } 

    public CustomerReport(User user) 
    { 
     User = user; 
     Enterprises = new List<NewEnterprise>(); 
     Customers = new List<NewCustomer>(); 
     Programs = new List<NewProgram>(); 
     InvoiceItems = new List<InvoiceItem>(); 
     ReportSelectionItems = new List<ReportSelectionItem>(); 
     Start = Code.StringExtensions.InputDate(new DateTime(2016, 01, 01)).ToString(); 
     End = Code.StringExtensions.InputDate(DateTime.Today).ToString(); 
    } 

    public CustomerReport(User user, List<NewEnterprise> enterprises, List<NewCustomer> customers, List<NewProgram> programs) 
    { 
     User = user; 
     Enterprises = enterprises; 
     Customers = customers; 
     Programs = programs; 
    } 

    public List<ReportSelectionItem> GetAllReportSelectionItems() 
    { 
     var items = new List<ReportSelectionItem>(); 
     foreach (var ent in Enterprises) 
     { 
      var item = new ReportSelectionItem(ent); 
      items.Add(item); 
     } 
     foreach (var cust in Customers) 
     { 
      var item = new ReportSelectionItem(cust); 
      items.Add(item); 
     } 
     foreach (var so in Programs) 
     { 
      var item = new ReportSelectionItem(so); 
      items.Add(item); 
     } 

     return items; 
    } 

    public List<ReportSelectionItem> ReportSelectionItemsSearch(string search) 
    { 
     var items = GetAllReportSelectionItems(); 
     var filteredItems = new List<ReportSelectionItem>(); 
     if (!String.IsNullOrWhiteSpace(search)) 
     { 
      filteredItems = items.Where(i => i.DisplayName.ToLower().Contains(search.ToLower())).ToList(); 
      return filteredItems; 
     } 
     return items; 
    } 

    public List<ReportSelectionItem> ReportSelectionItemsFilter(List<ReportSelectionItem> items, string type) 
    { 
     var filteredItems = new List<ReportSelectionItem>(); 
     if (!type.ToLower().Equals("all")) 
     { 
      filteredItems = items.Where(i => i.Type.ToLower().Contains(type.ToLower())).ToList(); 
      return filteredItems; 
     } 
     return items; 
    } 

    public void SearchAndFilter(string search, string searchType) 
    { 
     if (!String.IsNullOrWhiteSpace(search)) 
     { 
      this.FilteredSelectionItems = this.ReportSelectionItemsSearch(search); 
     } 
     if (!String.IsNullOrWhiteSpace(searchType)) 
     { 
      this.FilteredSelectionItems = this.ReportSelectionItemsFilter(this.ReportSelectionItems, searchType); 
     } 
    } 

    public void RemoveSlashFromDates(string start, string end) 
    { 
     if (start != null) 
     { 
      this.Start = start.Replace("/", ""); 
     } 
     if (end != null) 
     { 
      this.End = end.Replace("/", ""); 
     } 
    } 
} 

我的產品清單類選擇

public class ReportSelectionItem 
{ 
    public Guid ID { get; set; } 
    public string Name { get; set; } 
    public string DisplayName { get; set; } 
    public string Number { get; set; } 
    public string Type { get; set; } 
    public string TypeDisplay => GetTypeDisplay(Type); 
    public bool IsSelected { get; set; } 

    public ReportSelectionItem() 
    { 
     ID = Guid.NewGuid(); 
     IsSelected = false; 
    } 

    public ReportSelectionItem(NewEnterprise ent) : this() 
    { 
     Name = ent.Name; 
     DisplayName = ent.DisplayName; 
     Number = ent.EnterpriseNumber.ToString(); 
     Type = ent.GetType().ToString(); 
    } 

    public ReportSelectionItem(NewCustomer cust) : this() 
    { 
     Name = cust.Name; 
     DisplayName = cust.DisplayName; 
     Number = cust.Id.ToString(); 
     Type = cust.GetType().ToString(); 
    } 

    public ReportSelectionItem(NewProgram so) : this() 
    { 
     Name = so.Description; 
     DisplayName = so.DisplayName; 
     Number = so.ServiceOrderNumber.ToString(); 
     Type = so.GetType().ToString(); 
    } 

    public string GetTypeDisplay(string str) 
    { 
     if (str.ToLower().Contains("enterprise")) 
     { 
      return "Enterprise"; 
     }else if (str.ToLower().Contains("customer")) 
     { 
      return "Customer"; 
     }else if (str.ToLower().Contains("program")) 
     { 
      return "Program"; 
     } 
     else return str; 
    } 
} 

我的主視圖的選擇,裏面的語氣

@using System.Activities.Statements 
@model RecognitionReports.Web.ViewDataModels.CustomerReport 

@{ 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

<div class="row"> 
    <div class="col-xs-offset-1 col-xs-10"> 
     <div class="container"> 
      <div class="form-wrapper"> 
       <div class="search-form"> 
        @using (Html.BeginForm("New", "CustomerReports", FormMethod.Get)) 
        { 
         <form class="form"> 
         <fieldset> 
           @Html.Label("Search:", new { @class = "form-label" }) 
           <div class="form-group row"> 
            <div class="col-xs-offset-1 col-xs-10"> 
             <div class="input-group"> 
              @Html.TextBox("search", null, new { @class = "form-control", @placeholder = "Enter Selection Name or ID Number here..." }) 
              <span class="input-group-btn"> 
               <div class="btn-group"> 
                <a href="#" class="btn btn-info dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-search"></span> Search:</a> 
                <ul class="dropdown-menu"> 
                 <li><input name="searchType" type="submit" id="all" value="All" class="form-control btn btn-info" /></li> 
                 <li><input name="searchType" type="submit" id="ent" value="Enterprise" class="form-control btn btn-info" /></li> 
                 <li><input name="searchType" type="submit" id="cust" value="Customer" class="form-control btn btn-info" /></li> 
                 <li><input name="searchType" type="submit" id="so" value="Program" class="form-control btn btn-info" /></li> 
                </ul> 
               </div> 
              </span> 
             </div> 
            </div> 
           </div> 
          </fieldset> 
         </form> 
        } 
       </div> 

      <!-- Report Selection Modal --> 
      @{ Html.RenderPartial("_ReportSelectionOptionsModal", Model);} 
      <!-- Report Modal --> 
      @{ Html.RenderPartial("_ReportModal", Model); } 
     </div> 
    </div> 
</div> 

我的情態查看

@model RecognitionReports.Web.ViewDataModels.CustomerReport 

<div id="selection-modal" class="modal fade" role="dialog"> 
<div class="modal-dialog"> 
    <div class="modal-content"> 
     <div class="modal-header"> 
      <button type="button" class="close" data-dismiss="modal">&times;</button> 
      <h4 class="modal-title">Report Selection Options</h4> 
     </div> 
     @using (Html.BeginForm("SaveSelections", "CustomerReports", FormMethod.Post)) 
     { 

      <div class="modal-body"> 
       <table class="table table-condensed table-striped table-hover"> 
        <caption>All Report Options: </caption> 
        <thead> 
         <tr> 
          <th>Display Name</th> 
          <th>Type</th> 
          <th>Manage</th> 
         </tr> 
        </thead> 
        <tbody> 
         @foreach (var item in Model.FilteredSelectionItems) 
         { 
          <tr> 
           <td><strong>@item.DisplayName</strong></td> 
           <td>@item.TypeDisplay</td> 
           <td> 
            @Html.CheckBoxFor(i => item.IsSelected, new { @class = "check-box", Name=item.ID, id=item.ID }) 
           </td> 
          </tr> 
         } 
        </tbody> 
       </table> 
      </div> 
      <div class="modal-footer"> 
       <input type="submit" class="btn btn-success" name="action" value="Save"/> 
       <button type="button" class="btn btn-info" data-dismiss="modal">Close</button> 
      </div> 
     } 
    </div> 
</div> 

</div> 

可能的方法,我想傳遞給控制器​​

 [HttpPost] 
    public ActionResult SaveSelections(CustomerReport report) 
    { 
     //make sure selections are saved 
     return View("New", report); 
    } 

 [HttpPost] 
    public ActionResult SaveSelections(List<ReportSelectionItems> items) 
    { 
     //make sure selections are saved 
     return View("New", report); 
    } 

我已經嘗試了很多東西,並繼續傳遞參數爲空。我知道剃鬚刀在頁面渲染後將對象屬性變成字符串,但我看到有人將自定義對象作爲參數傳遞給控制器​​操作......我做錯了什麼?有一個更好的方法嗎?

編輯:更新的循環模式中的視圖:

@for (var i = 0; i < Model.FilteredSelectionItems.Count; i++) 
    { 
    <tr> 
     <td><strong>@Model.FilteredSelectionItems[i].DisplayName</strong></td> 
     <td>@Model.FilteredSelectionItems[i].TypeDisplay</td> 
     <td>@Html.CheckBoxFor(x => Model.FilteredSelectionItems[i].IsSelected, new { @class = "check-box", Name = Model.FilteredSelectionItems[i].ID, id = Model.FilteredSelectionItems[i].ID}) 
      @Html.HiddenFor(x => Model.FilteredSelectionItems[i].ID) 
     </td> 
    </tr> 
    } 

回答

0

你的表單中有唯一的字段是每個在FilteredSelectionItems屬性的元素的複選框。所以這是唯一的信息將會讓你的服務器。您可能需要調整一點點形式:

取而代之的是:

@foreach (var item in Model.FilteredSelectionItems) 
{ 
    <tr> 
     <td><strong>@item.DisplayName</strong></td> 
     <td>@item.TypeDisplay</td> 
     <td> 
      @Html.CheckBoxFor(i => item.IsSelected, new { @class = "check-box", Name=item.ID, id=item.ID }) 
     </td> 
    </tr> 
} 

使用本:

@for (var i = 0; i < Model.FilteredSelectionItems.Count; i++) 
{ 
    <tr> 
     <td><strong>@item.DisplayName</strong></td> 
     <td>@item.TypeDisplay</td> 
     <td> 
      @Html.CheckBoxFor(x => model.FilteredSelectionItems[i].IsSelected, new { @class = "check-box", Name=item.ID, id=item.ID }) 
     </td> 
    </tr> 
} 

現在你的控制器動作將成功地綁定到這一點:

[HttpPost] 
public ActionResult SaveSelections(CustomerReport report) 
{ 
    // only report.FilteredSelectionItems collection will be available here 
    // because that's the only thing you have input fields in the form 
    ... 
} 

如果您還需要填充其他字段,則可以從數據庫中檢索它們,sa我用你的GET動作檢索它們。然後與由視圖中用戶複選框選擇填充的FilteredSelectionItems集合的結果合併。

+0

非常感謝!我有這個主要工作,但是,它傳遞給參數時不保留選定的值,即如果我選中一個框並提交,傳遞的列表沒有任何IsSelected屬性設置爲true。我也嘗試爲reportSelectionItem ID添加一個hiddenfor字段 – Liveyourheart

相關問題