【问题标题】:MVC C#: Best way to bind a "list of dropdowns" with modelMVC C#:将“下拉列表”与模型绑定的最佳方式
【发布时间】:2019-04-08 15:43:53
【问题描述】:

我的模型无法与我的视图正确绑定,因此我需要一些帮助才能朝着正确的方向前进。

我正在处理“事故”,事故有一些属性,如年份、碰撞类型等,但在我的模型中,它还有一个伤害列表,每个伤害都是从下拉列表中选择的 (用户从近 100 种可能的伤害列表中进行选择)。

在某种程度上,我们可以说我的模型中有一个“下拉列表”(显然不是下拉列表,但我这样称呼它,这样您就知道我的问题从哪里开始了,那就是建模“列表列表”)。

这是我在共享视图文件夹中的 _InjuriesSelect 模板:

@model xxx.Models.AccidentViewModel

<div class="col-12 form-group text-dark mx-auto my-auto pb-2">
    <div class="container" style="padding-left:0;">
        <div class="row">
            <div class="col">
                @*@Html.DropDownListFor(model => model.Accident.Injuries, Model.Injuries, Model.SelectInjuryText, new { @class = "form-control", @style = "width: 300px;", onchange = @"" })*@
                @Html.DropDownList("selectInjuries_1", Model.InjuriesSelect, Model.SelectInjuryText, new { @class = "form-control", @style = "width: 300px;", onchange = @"" })
                @Html.ValidationMessageFor(model => model.Accident.Injuries, "", new { @class = "text-danger font-weight-bold" })
            </div>
            <div class="col">
                <a id="removeInjury_1" href="javascript: void(0);" style="text-decoration: none; visibility: hidden;" onclick="javascript: removeInjury(this);">
                    <i class="fa fa-minus text-danger pr-3" aria-hidden="true"></i>
                </a>
                <a id="addInjury_1" href="javascript: void(0);" style="text-decoration: none; visibility: hidden;" onclick="javascript: addInjury(this);">
                    <i class="fa fa-plus text-success" aria-hidden="true"></i>
                </a>
            </div>
        </div>
    </div>
</div>

我允许用户通过以下方式添加(或删除)下拉菜单以使用 javascript 添加/删除伤害:

function addInjury() {

    $.post("/Home/LoadInjurySelect", $("form").serialize(), function (data) {
        lastInjuryIndex++;

        //add holder for new injury
        var newInjurydivId = "divInjuries_" + lastInjuryIndex;
        var newInjuryDivHtml = "<div id='" + newInjurydivId + "'>";
        newInjuryDivHtml += data.replace(/_1/g, "_" + lastInjuryIndex);
        newInjuryDivHtml += "</div>";

        $("#divInjuries").append(newInjuryDivHtml);

        //hide "add injury" from previous injury
        $("#addInjury_" + (lastInjuryIndex - 1).toString()).css("visibility", "hidden");

        $("#selectInjuries_" + lastInjuryIndex).change(function () {
            var selectedInjury = $('#selectInjuries_' + lastInjuryIndex + ' option:selected').val();
            $("#addInjury_" + lastInjuryIndex).css("visibility", selectedInjury != "" ? "visible" : "hidden")
            //
            setInjuryInModel(selectedInjury);
        });


        setRemoveInjury1Visibility();
        setRemoveInjuryNVisibility(lastInjuryIndex);
    });
}

此javascript调用控制器并以这种方式返回部分视图:

[HttpPost]
public ActionResult LoadInjurySelect(AccidentViewModel model)
{
    model = fillViewModelLists(model);
    return PartialView("~/Views/Shared/_InjuriesSelect.cshtml", model);
}

此方法返回部分视图,但首先填充所有用于填充下拉列表的视图模型 IEnumerable 列表(如果没有,它们会丢失,因为 jQuery form.serialize 在序列化时不包括列表)。

我的事故模型如下所示:

using xxx.App_GlobalResources;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace xxx.Models
{
    public class Accident
    {
        //Person information

        [Display(Name = "home_accident_personname", ResourceType = typeof(languages))]
        //[Required(ErrorMessageResourceType = typeof(App_GlobalResources.languages), ErrorMessageResourceName = "home_accident_mustenterpersonname")]
        public string PersonName { get; set; }

        [Display(Name = "home_accident_personage", ResourceType = typeof(languages))]
        [Required(ErrorMessageResourceType = typeof(languages), ErrorMessageResourceName = "home_accident_agenotvalid")]
        public short PersonAge { get; set; }

        [Display(Name = "home_accident_personcondition", ResourceType = typeof(languages))]
        [Required(ErrorMessageResourceType = typeof(languages), ErrorMessageResourceName = "home_accident_conditionnotvalid")]
        public byte PersonCondition { get; set; }

        [Display(Name = "home_accident_personemail", ResourceType = typeof(languages))]
        //[Required(ErrorMessageResourceType = typeof(App_GlobalResources.languages), ErrorMessageResourceName = "home_accident_mustenterpersonemail")]
        [DataType(DataType.EmailAddress)]
        [EmailAddress]
        public string PersonEmail { get; set; }

        //Accident information

        [Display(Name = "home_accident_year", ResourceType = typeof(languages))]
        [Required(ErrorMessageResourceType = typeof(languages), ErrorMessageResourceName = "home_accident_yearnotvalid")]
        [Range(2016, 2019)]
        public short Year { get; set; }        

        [Display(Name = "home_accident_collisiontype", ResourceType = typeof(languages))]
        [Required(ErrorMessageResourceType = typeof(languages), ErrorMessageResourceName = "home_accident_collisiontypenotvalid")]
        public byte CollisionType { get; set; }

        [Display(Name = "home_accident_hospitalleave", ResourceType = typeof(languages))]
        [Range(0, int.MaxValue, ErrorMessageResourceType = typeof(languages), ErrorMessageResourceName = "home_accident_medicalleavenotvalid")]
        public short HospitalLeaveDays { get; set; }

        [Display(Name = "home_accident_workleave", ResourceType = typeof(languages))]
        [Range(0, int.MaxValue, ErrorMessageResourceType = typeof(languages), ErrorMessageResourceName = "home_accident_medicalleavenotvalid")]
        public short WorkLeaveDays { get; set; }

        [Display(Name = "home_accident_rehabilitationdays", ResourceType = typeof(languages))]
        [Range(0, int.MaxValue, ErrorMessageResourceType = typeof(languages), ErrorMessageResourceName = "home_accident_medicalleavenotvalid")]
        public short RehabilitationDays { get; set; }

        [Display(Name = "home_accident_injuries", ResourceType = typeof(languages))]
        public List<Injury> Injuries { get; set; }

        //Compensation

        public Compensation Compensation { get; set; }
    }
}

我的 AccidentViewModel 看起来像这样(由于可能受伤的数量很大,所以它相当长):

using xxx.App_GlobalResources;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Linq;

namespace xxx.Models
{
    public class AccidentViewModel
    {
        public Accident Accident { get; set; }

        public string SelectInjuryText { get { return languages.home_accident_selectinjury; } }

        /* VIEWMODEL LISTS / METHODS*/

        public IEnumerable<SelectListItem> Years { get; set; }

        public static IEnumerable<SelectListItem> fillYearsList()
        {
            List<SelectListItem> listItems = new List<SelectListItem>();
            int y = DateTime.Now.Year;
            for (int i = y; i >= y - 3; i--)
            {
                listItems.Add(new SelectListItem
                {
                    Text = i.ToString(),
                    Value = i.ToString()
                });
            }

            return listItems;
        }

        public IEnumerable<SelectListItem> Ages { get; set; }

        public static IEnumerable<SelectListItem> fillAgesList()
        {
            List<SelectListItem> listItems = new List<SelectListItem>();
            listItems.Add(new SelectListItem { Text = "", Value = "" });
            listItems.Add(new SelectListItem { Text = "0-16", Value = "900" });
            listItems.Add(new SelectListItem { Text = "16-25", Value = "850" });
            listItems.Add(new SelectListItem { Text = "25-35", Value = "800" });
            listItems.Add(new SelectListItem { Text = "35-45", Value = "750" });
            listItems.Add(new SelectListItem { Text = "45-65", Value = "700" });
            listItems.Add(new SelectListItem { Text = "65+", Value = "650" });

            return listItems;
        }

        public IEnumerable<SelectListItem> Conditions { get; set; }

        public static IEnumerable<SelectListItem> fillConditionsList()
        {
            List<SelectListItem> listItems = new List<SelectListItem>();
            listItems.Add(new SelectListItem { Text = "", Value = "" });
            listItems.Add(new SelectListItem { Text = languages.home_accident_condition_driver, Value = "1" });
            listItems.Add(new SelectListItem { Text = languages.home_accident_condition_companion, Value = Helpers.Utils.getFromWebConfig("successPercentageCompanion") });
            listItems.Add(new SelectListItem { Text = languages.home_accident_condition_pedestrian, Value = Helpers.Utils.getFromWebConfig("successPercentagePedestrian") });

            return listItems;
        }

        public IEnumerable<SelectListItem> Collisions { get; set; }

        public static IEnumerable<SelectListItem> fillCollisionsList()
        {
            List<SelectListItem> listItems = new List<SelectListItem>();
            listItems.Add(new SelectListItem { Text = "", Value = "" });
            listItems.Add(new SelectListItem { Text = languages.home_accident_collisionfront, Value = Helpers.Utils.getFromWebConfig("successPercentageCollisionFront") });
            listItems.Add(new SelectListItem { Text = languages.home_accident_collisionside, Value = Helpers.Utils.getFromWebConfig("successPercentageCollisionSide") });
            listItems.Add(new SelectListItem { Text = languages.home_accident_collisionrear, Value = Helpers.Utils.getFromWebConfig("successPercentageCollisionBack") });

            return listItems;
        }

        //

        public List<InjuryGroup> InjuriesGroups { get; set; }

        public static List<InjuryGroup> fillInjuriesGroupsList()
        {

            List<InjuryGroup> injuriesGroupsList = new List<InjuryGroup>();

            injuriesGroupsList.Add(new InjuryGroup { Id = 1, Name = InjuryGroups.Lesiones_AfectacionesNerviosas });
            injuriesGroupsList.Add(new InjuryGroup { Id = 2, Name = InjuryGroups.Lesiones_TranstornosPsicologicos });
            injuriesGroupsList.Add(new InjuryGroup { Id = 3, Name = InjuryGroups.Lesiones_LesionesOculares });
            injuriesGroupsList.Add(new InjuryGroup { Id = 4, Name = InjuryGroups.Lesiones_LesionesAuditivas });
            injuriesGroupsList.Add(new InjuryGroup { Id = 5, Name = InjuryGroups.Lesiones_LesionesNasales });
            injuriesGroupsList.Add(new InjuryGroup { Id = 6, Name = InjuryGroups.Lesiones_LesionesMandibulares });
            injuriesGroupsList.Add(new InjuryGroup { Id = 7, Name = InjuryGroups.Lesiones_LesionesCervicales });
            injuriesGroupsList.Add(new InjuryGroup { Id = 8, Name = InjuryGroups.Lesiones_LesionesExtremidadesSuperiores });
            injuriesGroupsList.Add(new InjuryGroup { Id = 9, Name = InjuryGroups.Lesiones_LesionesExtremidadesInferiores });
            injuriesGroupsList.Add(new InjuryGroup { Id = 10, Name = InjuryGroups.Lesiones_LesionesRodilla });
            injuriesGroupsList.Add(new InjuryGroup { Id = 11, Name = InjuryGroups.Lesiones_LesionesTobillo });
            injuriesGroupsList.Add(new InjuryGroup { Id = 12, Name = InjuryGroups.Lesiones_LesionesPie });
            injuriesGroupsList.Add(new InjuryGroup { Id = 13, Name = InjuryGroups.Lesiones_LesionesCadera });
            injuriesGroupsList.Add(new InjuryGroup { Id = 14, Name = InjuryGroups.Lesiones_LesionesCardiacas });
            injuriesGroupsList.Add(new InjuryGroup { Id = 15, Name = InjuryGroups.Lesiones_LesionesOrganoDigestivo });
            injuriesGroupsList.Add(new InjuryGroup { Id = 16, Name = InjuryGroups.Lesiones_LesionesSistemaUrinario });
            injuriesGroupsList.Add(new InjuryGroup { Id = 17, Name = InjuryGroups.Lesiones_Quemaduras });
            injuriesGroupsList.Add(new InjuryGroup { Id = 18, Name = InjuryGroups.Lesiones_LesionesNeurologicasMedulares });
            injuriesGroupsList.Add(new InjuryGroup { Id = 19, Name = InjuryGroups.Lesiones_LesionesRespitarorias });

            return injuriesGroupsList;
        }

        public List<SelectListGroup> InjuriesSelectGroups { get; set; }

        public static List<SelectListGroup> fillInjuriesSelectListGroup(AccidentViewModel model) {

            List<SelectListGroup> injuriesSelectListGroup = new List<SelectListGroup>();
            foreach (InjuryGroup injuryGroup in model.InjuriesGroups) {
                injuriesSelectListGroup.Add(new SelectListGroup { Name = injuryGroup.Name });
            }

            return injuriesSelectListGroup;
        }

        //

        public List<Injury> Injuries { get; set; }        

        public static List<Injury> fillInjuriesList(AccidentViewModel model)
        {
            InjuryGroup Lesiones_AfectacionesNerviosas = model.InjuriesGroups[0];
            InjuryGroup Lesiones_TranstornosPsicologicos = model.InjuriesGroups[1];
            InjuryGroup Lesiones_LesionesOculares = model.InjuriesGroups[2];
            InjuryGroup Lesiones_LesionesAuditivas = model.InjuriesGroups[3];
            InjuryGroup Lesiones_LesionesNasales = model.InjuriesGroups[4];
            InjuryGroup Lesiones_LesionesMandibulares = model.InjuriesGroups[5];
            InjuryGroup Lesiones_LesionesCervicales = model.InjuriesGroups[6];
            InjuryGroup Lesiones_LesionesExtremidadesSuperiores = model.InjuriesGroups[7];
            InjuryGroup Lesiones_LesionesExtremidadesInferiores = model.InjuriesGroups[8];
            InjuryGroup Lesiones_LesionesRodilla = model.InjuriesGroups[9];
            InjuryGroup Lesiones_LesionesTobillo = model.InjuriesGroups[10];
            InjuryGroup Lesiones_LesionesPie = model.InjuriesGroups[11];
            InjuryGroup Lesiones_LesionesCadera = model.InjuriesGroups[12];
            InjuryGroup Lesiones_LesionesCardiacas = model.InjuriesGroups[13];
            InjuryGroup Lesiones_LesionesRespitarorias = model.InjuriesGroups[14];
            InjuryGroup Lesiones_LesionesOrganoDigestivo = model.InjuriesGroups[15];
            InjuryGroup Lesiones_LesionesSistemaUrinario = model.InjuriesGroups[16];
            InjuryGroup Lesiones_Quemaduras = model.InjuriesGroups[17];
            InjuryGroup Lesiones_LesionesNeurologicasMedulares = model.InjuriesGroups[18];

            List<Injury> injuries = new List<Injury>();

            injuries.Add(new Injury { Id = 1, Text = languages.Lesiones_AfectacionesNerviosas_AfectacionNerviosaAuditiva, Value = int.Parse(Helpers.Utils.getFromWebConfig("Lesiones_AfectacionesNerviosas_AfectacionNerviosaAuditiva")), Group = Lesiones_AfectacionesNerviosas });
            injuries.Add(new Injury { Id = 2, Text = languages.Lesiones_AfectacionesNerviosas_AfectacionNerviosaOcular, Value = int.Parse(Helpers.Utils.getFromWebConfig("Lesiones_AfectacionesNerviosas_AfectacionNerviosaOcular")), Group = Lesiones_AfectacionesNerviosas });
            injuries.Add(new Injury { Id = 3, Text = languages.Lesiones_AfectacionesNerviosas_AfectacionNervioCiatico, Value = int.Parse(Helpers.Utils.getFromWebConfig("Lesiones_AfectacionesNerviosas_AfectacionNervioCiatico")), Group = Lesiones_AfectacionesNerviosas });
            injuries.Add(new Injury { Id = 4, Text = languages.Lesiones_AfectacionesNerviosas_AfectacionNerviosaMandibular, Value = int.Parse(Helpers.Utils.getFromWebConfig("Lesiones_AfectacionesNerviosas_AfectacionNerviosaMandibular")), Group = Lesiones_AfectacionesNerviosas });
            injuries.Add(new Injury { Id = 5, Text = languages.Lesiones_AfectacionesNerviosas_AfectacionNerviosaRadioCubito, Value = int.Parse(Helpers.Utils.getFromWebConfig("Lesiones_AfectacionesNerviosas_AfectacionNerviosaRadioCubito")), Group = Lesiones_AfectacionesNerviosas });
            injuries.Add(new Injury { Id = 6, Text = languages.Lesiones_AfectacionesNerviosas_AfectacionNerviosaTibia, Value = int.Parse(Helpers.Utils.getFromWebConfig("Lesiones_AfectacionesNerviosas_AfectacionNerviosaTibia")), Group = Lesiones_AfectacionesNerviosas });

            ...

            return injuries;
        }

        public IEnumerable<SelectListItem> InjuriesSelect { get; set; }

        public static IEnumerable<SelectListItem> fillInjuriesSelectList(AccidentViewModel model)
        {
            List<SelectListItem> injuriesSelectList = new List<SelectListItem>();

            foreach (InjuryGroup injuryGroup in model.InjuriesGroups) {
                foreach (Injury injury in model.Injuries.Where(x => x.Group == injuryGroup).ToList()) {
                    injuriesSelectList.Add(new SelectListItem { Text = injury.Text, Value = injury.Id.ToString(), Group = model.InjuriesSelectGroups.Where(x => x.Name == injuryGroup.Name).First() });
                }
            }

            return injuriesSelectList;
        }
    }

损伤模型:

using xxx.App_GlobalResources;

namespace xxx.Models
{
    public class Injury
    {
        public int Id { get; set; }
        public string Text { get; set; }
        public int Value { get; set; }
        public InjuryGroup Group { get; set; }
    }

    public static class InjuryGroups
    {
        public static string Lesiones_AfectacionesNerviosas { get { return languages.Lesiones_AfectacionesNerviosas; } }
        public static string Lesiones_TranstornosPsicologicos { get { return languages.Lesiones_TranstornosPsicologicos; } }
        public static string Lesiones_LesionesOculares { get { return languages.Lesiones_LesionesOculares; } }
        public static string Lesiones_LesionesAuditivas { get { return languages.Lesiones_LesionesAuditivas; } }
        public static string Lesiones_LesionesNasales { get { return languages.Lesiones_LesionesNasales; } }
        public static string Lesiones_LesionesMandibulares { get { return languages.Lesiones_LesionesMandibulares; } }
        public static string Lesiones_LesionesCervicales { get { return languages.Lesiones_LesionesCervicales; } }
        public static string Lesiones_LesionesExtremidadesSuperiores { get { return languages.Lesiones_LesionesExtremidadesSuperiores; } }
        public static string Lesiones_LesionesExtremidadesInferiores { get { return languages.Lesiones_LesionesExtremidadesInferiores; } }
        public static string Lesiones_LesionesRodilla { get { return languages.Lesiones_LesionesRodilla; } }
        public static string Lesiones_LesionesTobillo { get { return languages.Lesiones_LesionesTobillo; } }
        public static string Lesiones_LesionesPie { get { return languages.Lesiones_LesionesPie; } }
        public static string Lesiones_LesionesCadera { get { return languages.Lesiones_LesionesCadera; } }
        public static string Lesiones_LesionesCardiacas { get { return languages.Lesiones_LesionesCardiacas; } }
        public static string Lesiones_LesionesRespitarorias { get { return languages.Lesiones_LesionesRespitarorias; } }
        public static string Lesiones_LesionesOrganoDigestivo { get { return languages.Lesiones_LesionesOrganoDigestivo; } }
        public static string Lesiones_LesionesSistemaUrinario { get { return languages.Lesiones_LesionesSistemaUrinario; } }
        public static string Lesiones_Quemaduras { get { return languages.Lesiones_Quemaduras; } }
        public static string Lesiones_LesionesNeurologicasMedulares { get { return languages.Lesiones_LesionesNeurologicasMedulares; } }
    }
}

InjuryGroup 模型:

使用 System.Collections.Generic;

命名空间补偿Calc.Models { 公开课 InjuryGroup { 公共 int ID { 获取;放; } 公共字符串名称 { 获取;放; } 公开伤害清单{得到;放; } } }

最后,我无法做的是将伤害下拉列表与模型绑定,因此当提交表单时,伤害列表包含所有选定的伤害,换句话说,当用户选择(添加)一个新的伤害模型用相应的值更新它的伤害列表。

我也不明白(这是概念性的)是,如果我通过 PartialView 使用模板添加伤害下拉列表并通过 javascript 发布调用来执行此操作,那么新添加的下拉列表 ID 会发生什么情况?我是否必须使用 javascript 重命名它们,以便每次添加新伤害时不会在 DOM 中重复新的下拉 ID?

最重要的是在将我的“下拉列表”与我的事故模型绑定的最佳方法上获得一些帮助(当然,还要让每个新添加的下拉列表也与模型绑定)。

我知道我应该使用 DropDownListFor 而不是 DropDownList,但我不知道该怎么做。

谢谢。

【问题讨论】:

    标签: c# asp.net-mvc model dropdown


    【解决方案1】:

    好吧,我将结束回答我自己的问题,以防它帮助其他面临类似问题的人。

    如果您的模型中有一个列表,则一种处理方法是下一个:

    在模型中,我添加了一个新属性来保存下拉列表中的 SelectedInjury(在我的情况下)。

    public int SelectedInjury { get; set; }
    

    在视图中我以这种方式创建 DropDownList:

    @Html.DropDownListFor(model => model.Accident.Injuries[0].SelectedInjury, Model.Injuries, Model.SelectInjuryText, new { @class = "form-control", @style = "width: 300px;", onchange = @"" })
    

    然后,在 javascript 中,我有一个 Injury 计数器,每当添加新的 DropDowns(通过 ajax 调用来自模板的控制器)时,我只需替换 Accident_Injuries[0] 中的“0”(这或多或少是在将 html 添加到 DOM 之前,使用相应的新索引生成 html id)。这样,当您在下拉列表中选择一个新项目时,一个新的 Injury 对象会自动添加到列表中,因此模型会更新,而无需对控制器或其他任何东西进行 ajax 调用(这是我的邮件问题)。

    干杯,编码愉快!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多