从视图将集合传递给控制器

时间:2015-10-20 01:55:03

标签: c# asp.net-mvc-4 asp.net-mvc-5

我有一个模型绑定到视图。我想添加一个复选框,允许用户更改选择并为另一个进程提交所选项目。如果需要,用户还可以更改NumberOfCopies的值。

我将ManufacturingJobEditModel传递给控制器​​。我可以在控制器的PrintErrors集合中看到所有项目。但是,我有2个问题

  1. ManufacturingJob在控制器的ManufacturingJobEditModel中始终为NULL
  2. 只有IsSelectedNumberOfCopies才有值。其余属性显示NULL值。
  3. 这是我在这里缺少的吗?

    模型

    public class ManufacturingJobProductEditModel
    {
        public ManufacturingJob ManufacturingJob{ get; set;}
        public IList<PrintError> PrintErrors { get; set; }
    }
    
    public class PrintError
    {
        public bool IsSelected { get; set; }
        public int ProductId { get; set; }
        public string ISBN { get; set; }
        public string ProductName { get; set; }
        public int Sequence { get; set; }
        public int NumberofCopies { get; set; }
    }
    

    的MainView

    <table>
        <tr>
            <td class="display-label valign-top">Products</td>
            <td class="display-field white-space-reset"
                colspan="3">
                <table class="formDisplayTable">
                    <colgroup>
                        <col class="width05" />
                        <col class="width10" />
                        <col class="width10" />
                        <col class="width35" />
                        <col class="width05" />
                        <col class="width20" />
                    </colgroup>
                    <thead>
                        <tr>
                            <th></th>
                            <th>ISBN</th>
                            <th>Product ID</th>
                            <th>ProductName</th>
                            <th>Sequence Number</th>
                            <th>No of Copies</th>
                        </tr>
                    </thead>
                    <tbody>@foreach (var product in Model.ManufacturingJob.ManufacturingJobProducts.OrderBy(c => c.Sequence))
                            {
                                Html.RenderPartial("_PrintErrorDetails", product);
                            }</tbody>
                </table>
            </td>
        </tr>
    </table>
    

    _PrintErrorDetails.cshtml

    @model Bolinda.Matrix.Data.Domain.ManufacturingJobProduct
    @{Html.RegisterFormContextForValidation();} 
    
    <tr class="valign-top">
        @using (Html.BeginCollectionItem("PrintErrors"))
        {
            <td>
                <div class="editor-field">@Html.CheckBox("IsSelected")</div>
            </td>
            <td>
                <div class="table-display-field">@Html.Display("ISBN")</div>
            </td>
            <td>
                <div class="table-display-field">@Html.Display("ManufacturingProduct.Product.ProductId")</div>
            </td>
            <td>
                <div class="table-display-field">@Html.Display("ManufacturingProduct.Product.Name")</div>
            </td>
            <td>
                <div class="table-display-field">@Html.Display("Sequence")</div>
            </td>
            <td>
                <div class="table-editor-field">@Html.Editor("NumberOfCopies")</div>
            </td>
        }
    </tr>
    

    控制器

    [HttpPost]
    public ActionResult PrintError(ManufacturingJobProductEditModel editModel)
    {
        var id = editModel.ManufacturingJob.ManufacturingJobId;
        ManufacturingJob manufacturingJob = _unitOfWork.ManufacturingJob
                                                .GetWhere(j => j.ManufacturingJobId == id, null, "ManufacturingJobProducts")
                                                .FirstOrDefault();
        if (manufacturingJob == null)
        {
            return new HttpNotFoundResult(String.Format("Manufacturing Job with id {0} was not found.", id));
        }
    
      //  _service.RequeueErrorCorrection(manufacturingJob, printErrorCorrection, autoCdErrorCorrection, manualCdErrorCorrectionSequenceNumbers);
        return RedirectToAction("Details", new { id = manufacturingJob.ManufacturingJobId });
    }
    

2 个答案:

答案 0 :(得分:1)

  

ManufacturingJob在控制器的ManufacturingJobEditModel中始终为NULL

您显示的视图不会为任何属性生成任何表单控件,因此不会回发任何值并将其绑定到模型。从POST方法中的代码,您似乎只需要ManufacturingJobId属性,因此您需要包含

@Html.HiddenFor(m => m.ManufacturingJob.ManufacturingJobId)
  

只有IsSelected和NumberOfCopies具有值。其余属性显示NULL值

同样,您没有为集合中每个IsSelected对象的NumberOfCopiesPrintError以外的任何属性添加表单控件。如果要绑定其他属性,请使用

<td>
    <div class="table-display-field">@Html.Display("ISBN")</div>
    @Html.HiddenFor(m => m.ISBN)
</td>

<td>
    <div class="table-display-field">@Html.TextboxFor(m => m.ISBN, new { @readonly = "readonly" })</div>
</td>

附注:由于您未在视图中动态添加或删除PrintError项,因此无需使用BeginCollectionItem()的额外开销。使用for循环或自定义EditorTemplate作为PrintError类型,并在主视图中使用@Html.EditorFor(m => m.PrintErrors)(有关使用EditorTemplate的示例,请参阅this answer )。我还建议您在将模型PrintError集合传递给视图(包括.Order()子句)之前填充模型Button集合,而不是尝试“伪造”它。正如您所做的那样。 p>

答案 1 :(得分:0)

这是因为您没有为“ IsSelected ”和“ NumberOfCopies ”以外的其他模型属性渲染html输入控件。

“@ Html。显示”只是在没有任何html输入控件的情况下呈现数据。您可以使用页面查看源进行检查。

要渲染这些控件,您可以使用以下html辅助方法。的 @Html。 TextBox @Html。 DropDown @Html。 TextArea 和其他人。

要提交进一步处理所需的所有属性,您必须呈现与该属性对应的html输入控件。只有这样你才能提交这些属性。

如果问题仍然存在,请告诉我。