2017-01-16 77 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

相关问题