2017-01-16 17 views
2

私はMVC 5で私の最初のプロダクションアプリケーションを書いています。httpのポストアクションにパラメータとしてカスタムオブジェクトを渡そうとしています私のコントローラで。基本的には、CustomerReport View Modelにラップされたビューを持っています。そのモデルでは、モデルから項目を選択するオプションを持つモーダルを作成し、ビューモデルを渡すコントローラアクションを通じて選択を保存します(またはビューモデルのプロパティ)をパラメータとして使用します。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> 

私のモーダルを収容する私のメインビューの選択から選択する項目のリストについては、私のクラス表示

私は多くのことを試してみたし、それがnullとしてパラメータを渡すために続けて、コントローラ

 [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

関連する問題