使用Model Binder的ASP.NET MVC SelectList项

时间:2015-12-04 22:31:37

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

我有一个接受复杂对象参数的控制器,它本身具有复杂的类型集合属性。在表单发布后,模型绑定对我的损坏属性不起作用(它总是为空)。如何为损坏属性构建下拉列表,以便在将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之后,下拉菜单会根据它们的值进行填充和选择,但是当我发布表单时,damage属性在到达post action方法时为null。

1 个答案:

答案 0 :(得分:0)

您的模型绑定不起作用,因为您正在错误地使用模型。使用for循环而不是foreach并使用DropDownListFor在for循环内部使用适当的DamageViewModel。然后,您将获得模型绑定所需的一切。请记住,永远不要尝试通过自己的代码模仿模型绑定,因为它容易出错并且很难在以后进行更改,因为总是存在这种可能性。