【问题标题】:ASP.NET MVC SelectList items with Model Binder带有模型绑定器的 ASP.NET MVC SelectList 项
【发布时间】:2015-12-04 22:31:36
【问题描述】:

我有一个控制器,它接受一个复杂的对象参数,它本身有一个复杂的类型集合属性。表单发布后,模型绑定对我的损害属性不起作用(它始终为空)。如何为我的损坏属性构建下拉列表,以便在将 html 表单发布到控制器时使用选定的值填充模型?

注意-我是 ASP.NET MVC 的新手,这是我被要求调试的预先编写的代码。

查看模型 1:

public class EditInspectionViewModel
    {
        public long? InsRefreshSeq { get; set; }
        public string Inspector { get; set; }
        public string VIN { get; set; }
        public string Manufacturer { get; set; }
        public string Plant { get; set; }
        public string Model { get; set; }
        public IEnumerable<DamageViewModel> Damages { get; set; }

        public IEnumerable<GETAREAResult> AreaFilterOptions { get; set; }
        public IEnumerable<GETDMGTYPEResult> DamageTypeFilterOptions { get; set; }
        public IEnumerable<GETSEVERITYResult> SeverityFilterOptions { get; set; }
        public IEnumerable<GETGRIDResult> GridFilterOptions { get; set; }     
    }

查看模型 2:

 public class DamageViewModel
{
    public long DamageId { get; set; }
    public string Area { get; set; }
    public string AreaCode { get; set; }
    public string TypeCode { get; set; }
    public string SeverityCode { get; set; }
    public string GridCode { get; set; }
    public string Type { get; set; }
    public string Severity { get; set; }
    public string Grid { get; set; }
    public bool HasError { get; set; }
    public bool HasAreaError { get; set; }
    public bool HasDamageTypeError { get; set; }
    public bool HasSeverityError { get; set; }
    public bool HasImages { get; set; }        
}

控制器编辑方法:

[HttpGet]
    public virtual ActionResult Edit(long id)
    {

            EditInspectionViewModel viewModel = _getInspectionForEditingQuery.Execute(CurrentUserId, id);
            viewModel.InsRefreshSeq = 0;
            viewModel.AreaFilterOptions = _refService.GetAreas().OrderBy(x => x.ARECODE);
            viewModel.DamageTypeFilterOptions = _refService.GetDamageTypes().OrderBy(x => x.DTPCODE);
            viewModel.SeverityFilterOptions = _refService.GetSeverities().OrderBy(x => x.SEVCODE);
            viewModel.GridFilterOptions = _refService.GetQuadrants().OrderBy(x => x.QUDCODE);

         return View(viewModel);
     }


[HttpPost]
    public virtual ActionResult Edit( long id, EditInspectionViewModel editedInspection)
    {
        if (ModelState.IsValid)
        {
            _updateErrorInspectionCommand.Execute(editedInspection);

            return View(editedInspection);
        }

        return View(editedInspection);
    }

这是显示检查损坏的部分剃须刀视图(此视图和外部视图都输入到 EditInspectionViewModel):

        @model AIM.NewCars.Model.Inspections.EditInspectionViewModel

    @{

    }

<div class="panel panel-info">
    <div class="panel-heading clearfix">


    </div>
    <table class="table table-condensed">
        <thead>
            <tr>
                <th>Area</th>
                <th>Type</th>
                <th>Severity</th>
                <th>Grid</th>
                <th>Images</th>
                <th>Remove</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var damage in Model.Damages)
            {
                if (damage.HasError)
                {
                    IEnumerable<SelectListItem> areas = Model.AreaFilterOptions.Select(x => new SelectListItem() { Value = x.ARECODE, Text = x.ARECODE + "-" + x.AREDESC, Selected = damage.AreaCode == x.ARECODE });
                    IEnumerable<SelectListItem> damageTypes = Model.DamageTypeFilterOptions.Select(x => new SelectListItem() { Value = x.DTPCODE, Text = x.DTPCODE + "-" + x.DTPDESC, Selected = damage.TypeCode == x.DTPCODE });
                    IEnumerable<SelectListItem> severities = Model.SeverityFilterOptions.Select(x => new SelectListItem() { Value = x.SEVCODE, Text = x.SEVCODE + "-" + x.SEVDESC, Selected = damage.SeverityCode == x.SEVCODE });
                    IEnumerable<SelectListItem> grids = Model.GridFilterOptions.Select(x => new SelectListItem() { Value = x.QUDCODE, Text = x.QUDCODE + "-" + x.QUDDESC, Selected = damage.GridCode == x.QUDCODE });

                    <tr class="damage-container">
                        <td>
                            <input type="hidden" name="@("InspectionDamages[" + Model.Index + "].Index")" value="@Model.Index" />

                            @Html.DropDownList("InspectionDamages[" + damage.DamageId + "].AreaCode", areas, string.Empty, new { @class = "form-control js-damage-field" })
                        </td>
                        <td>

                            @Html.DropDownList("Damages[" + damage.DamageId + "].DamageTypeCode", damageTypes, string.Empty, new { @class = "form-control js-damage-field" })
                        </td>
                        <td>

                            @Html.DropDownList("InspectionDamages[" + damage.DamageId + "].SeverityCode", severities, string.Empty, new { @class = "form-control js-damage-field" })
                        </td>
                        <td>

                            @Html.DropDownList("InspectionDamages[" + damage.DamageId + "].GridCode", grids, string.Empty, new { @class = "form-control js-damage-field" })
                        </td>
                  }
        </tbody>
        </table>
       </div>

在 http get 之后,下拉菜单会根据它们的值进行填充和选择,但是当我发布表单时,当它到达 post 操作方法时,damages 属性为空。

【问题讨论】:

  • 将您的集合属性设为IList&lt;T&gt; 并使用for 循环(不是foreach 循环或为您的类型使用自定义EditorTemplate。

标签: asp.net-mvc razor model-binding


【解决方案1】:

您的模型绑定不起作用,因为您以错误的方式使用模型。使用 for 循环而不是 foreach 并在 for 循环内使用 DropDownListFor 来获得适当的 DamageViewModel。然后你会得到所有你需要的表单模型绑定。请记住,永远不要尝试通过您自己的代码来模拟模型绑定,因为这很容易出错并且很难在以后进行更改,因为总是有这种可能性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 2011-03-15
    相关资源
    最近更新 更多