【问题标题】:How to set the value of dropdown coming from model in ASP.NET MVC如何在 ASP.NET MVC 中设置来自模型的下拉列表的值
【发布时间】:2016-11-14 16:37:12
【问题描述】:

我被困在“如何将下拉菜单中的值设置为模型中设置的值。

我正在添加我到目前为止所拥有的以及我尝试过的。

所以,我有一个 PaymentFormMV 模型,其中还有另一个模型 PaymentCCMV

public class PaymentFormMV
{
    public PaymentCCMV CreditDetails { get; set; }
    public string ModelPropertyPrefixName
    {
        get
        {
            return this.ModelPropertyPrefix.Replace("_", ".");
        }
    }
}
public class PaymentCCMV
{
    [Display(Name = "Expiration Date")]
    public int ExpirationMonth { get; set; }
}

cshtml 文件从 PaymentFormMV 获取数据

<div class="form-group">
    @Html.LabelFor(model => model.CreditDetails.ExpirationMonth, htmlAttributes: new { @class = "control-label col-md-2 required" })
    <div class="col-md-10">
        @Html.DropDownList(Model.ModelPropertyPrefixName + "CreditDetails.ExpirationMonth", Helpers.PossibleMonths,
        new { id = Model.ModelPropertyPrefix + "CreditDetails_ExpirationMonth", @class = "form-control", style = "width:70px;" })
    </div>
</div>

Helpers.PossibleMonths:显示所有月份

public static ICollection<SelectListItem> PossibleMonths
{
    get
    {
        return new List<SelectListItem>()
        {
            new SelectListItem() { Text = "1 - Jan", Value = "1" },
            new SelectListItem() { Text = "2 - Feb", Value = "2" },
            new SelectListItem() { Text = "3 - Mar", Value = "3" },
            new SelectListItem() { Text = "4 - Apr", Value = "4" },
            new SelectListItem() { Text = "5 - May", Value = "5" },
            new SelectListItem() { Text = "6 - Jun", Value = "6" },
            new SelectListItem() { Text = "7 - Jul", Value = "7" },
            new SelectListItem() { Text = "8 - Aug", Value = "8" },
            new SelectListItem() { Text = "9 - Sep", Value = "9" },
            new SelectListItem() { Text = "10 - Oct", Value = "10" },
            new SelectListItem() { Text = "11 - Nov", Value = "11" },
            new SelectListItem() { Text = "12 - Dec", Value = "12" },
        };
    }
}

积分:

我得到整数值 model.CreditDetails.ExpirationMonth = 2(根据 DB)

但我不知道如何将其设置为下拉菜单。因此,当屏幕加载时,我希望该值与下拉列表相关联。请指导我。所以,如果值为 2,我应该在帮助方法中提到的下拉 UI 中得到类似 2 - Feb 的内容。我是初学者,所以我可能没有遵循最佳实践,所以请耐心等待。

生成的 HTML:

【问题讨论】:

  • 一种方法是使用 HTML.DropDownListFor。然后,如果需要,您可以将模型和默认值作为 SelectList 和 htmlAttributes 提供。
  • 非常感谢您的回复。你能详细说明一下吗?
  • 将您的代码更改为@Html.DropDownListFor(m =&gt; m.CreditDetails.ExpirationMonth, Helpers.PossibleMonths, new { @class = "form-control", style = "width:70px;" })。如果ExpirationMonth 的值是3,那么"Mar" 将被选中。
  • 附带说明,您的助手可以简化为return Enumerable.Range(1, 12).Select(x =&gt; new SelectListItem{ Value = x.ToString(), Text = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x));
  • @StephenMuecke:非常感谢您的指导。

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


【解决方案1】:

我支持@Vivien 的回复,但我建议使用采用所选值 (See MSDN:) 的重载,然后您可以对其进行设置。然后允许传入默认值,我还建议使用静态方法,并允许传入月份:

public static SelectList PossibleMonths(string defaultValue)
{
        return new SelectList(List<SelectListItem>()
        {
            new SelectListItem() { Text = "1 - Jan", Value = "1" },
            new SelectListItem() { Text = "2 - Feb", Value = "2" },
            new SelectListItem() { Text = "3 - Mar", Value = "3" },
            new SelectListItem() { Text = "4 - Apr", Value = "4" },
            new SelectListItem() { Text = "5 - May", Value = "5" },
            new SelectListItem() { Text = "6 - Jun", Value = "6" },
            new SelectListItem() { Text = "7 - Jul", Value = "7" },
            new SelectListItem() { Text = "8 - Aug", Value = "8" },
            new SelectListItem() { Text = "9 - Sep", Value = "9" },
            new SelectListItem() { Text = "10 - Oct", Value = "10" },
            new SelectListItem() { Text = "11 - Nov", Value = "11" },
            new SelectListItem() { Text = "12 - Dec", Value = "12" },
        }, "Value", "Text", defaultValue);
}

编辑:您的下拉菜单可能看起来像

@Html.DropDownList(Model.ModelPropertyPrefixName + "CreditDetails.ExpirationMonth", Helpers.PossibleMonths(Model.CreditDetails.ExpirationMonth),
                new { id = Model.ModelPropertyPrefix + "CreditDetails_ExpirationMonth", @class = "form-control", style = "width:70px;" })

假设 CreditDetails 对象始终不为空,否则必须进行空检查。

编辑:我错了,显然 Html.DropDownList 不支持 SelectList,所以我恢复到原来的方法,改变了设置所选值(请注意上面相同的下拉代码才能工作)。

public static IEnumerable<SelectListItem> PossibleMonths(string defaultValue)
{
        if (defaultValue == null)
           defaultValue = "";

        return new List<SelectListItem>()
        {
            new SelectListItem() { Text = "1 - Jan", Value = "1", Selected = (defaultValue == "1") },
            new SelectListItem() { Text = "2 - Feb", Value = "2", Selected = (defaultValue == "2") },
            new SelectListItem() { Text = "3 - Mar", Value = "3", Selected = (defaultValue == "3") },
            new SelectListItem() { Text = "4 - Apr", Value = "4", Selected = (defaultValue == "4") },
            new SelectListItem() { Text = "5 - May", Value = "5", Selected = (defaultValue == "5") },
            new SelectListItem() { Text = "6 - Jun", Value = "6", Selected = (defaultValue == "6") },
            new SelectListItem() { Text = "7 - Jul", Value = "7", Selected = (defaultValue == "7") },
            new SelectListItem() { Text = "8 - Aug", Value = "8", Selected = (defaultValue == "8") },
            new SelectListItem() { Text = "9 - Sep", Value = "9", Selected = (defaultValue == "9") },
            new SelectListItem() { Text = "10 - Oct", Value = "10", Selected = (defaultValue == "10") },
            new SelectListItem() { Text = "11 - Nov", Value = "11", Selected = (defaultValue == "11") },
            new SelectListItem() { Text = "12 - Dec", Value = "12", Selected = (defaultValue == "12") },
        };
}

【讨论】:

  • 您能否指导我如何根据您的帮助代码更改我的 cshtml 文件。
  • 据我研究,我需要在@Html.DropDownList 中再传递一个参数(告诉下拉菜单采用默认值并显示它)对吗?
  • 另外,当我说默认值时,我的意思是说记录的是用户的模型数据。我的意思是表格需要由模型数据自动填充。不是硬编码的默认值。只是说。我相信你会想出来的。
  • 不,选择的值不是 Html.DropDownList 上的属性。您要么需要在 SelectListItem 类上设置 Selected 属性,要么使用 SelectList 并指定所选值参数(我上面的方法中的第 4 个参数)。视图将存储在模型中的值作为默认值传递(是的,我们没有硬编码“2”值)。
  • 我的错,我原来的方法是错误的,而 Vivien 是对的,但结果是 Html.DropDownList 根本不支持 SelectList,所以我只是修改了你原来的方法,将 selected 属性设置为正确的入口。您也许可以使用 SelectList 类并使用 Items 属性来获取 SelectListItem 集合的列表,因此任何一种方法都应该有效。
【解决方案2】:

DropDownList()(和首选的DropDownListFor() 方法通过绑定到您的属性的值来工作。在您的情况下,您想绑定到ExpirationMonth 属性,您视图中的代码应该是

@Html.DropDownList("CreditDetails.ExpirationMonth", Helpers.PossibleMonths, new { @class = "form-control", style = "width:70px;" }

或更好

@Html.DropDownListFor(m => m.CreditDetails.ExpirationMonth, Helpers.PossibleMonths, new { @class = "form-control", style = "width:70px;" }

如果您在 GET 方法中将 ExpirationMonth 的值设置为 3 并将模型传递给视图,则将选择第三个选项(“Mar”)。

尚不清楚您的 ModelPropertyPrefixModelPropertyPrefixName 属性返回什么,但它们不是必需的,并且不应在视图中使用(HtmlHelper 方法将始终生成正确的 name 必要属性用于 2 向模型绑定)。

另请注意,认为在生成SelectList 时需要设置SelectListItemSelected 属性是一种常见的误解。当绑定到模型属性时,DropDownList()DropDownListFor() 方法在内部生成它们自己的IEnumerable&lt;SelectListItem&gt; 并根据属性的值设置Selected 属性(任何自己设置它的尝试都会被忽略)。唯一尊重 Selected 属性的情况是当您使用 DropDownList("xxx", ...) 并且 xxx 不是属性或模型时。

附带说明一下,您在静态方法中的代码可能只是

public static IEnumerable<SelectListItem> PossibleMonths()
{
    return Enumerable.Range(1, 12).Select(x => new SelectListItem()
    {
        Value = x.ToString(),
        Text = System.Globalization.CultureInfo.CurrentCulture.DateTimeForm‌at.GetMonthName(x)
    });
}

并且您的视图模型不应包含在编辑数据时属于数据模型的属性。 PaymentFormMV 应该包含public int ExpirationMonth { get; set; }(以及您需要的PaymentCCMV 的其他属性),而不是public PaymentCCMV CreditDetails { get; set; }


根据您显示 html 图像的编辑,您生成的 name 属性与视图中使用的 PaymentFormMV 模型无关(它没有名为 PaymentInfo 的属性)因此您没有正确绑定到模型,并且不会选择正确的选项。

从聊天中的cmets,你需要将视图更改为使用@model MoveInMV,然后方法将是

@Html.DropDownListFor(m => m.PaymentInfo.CreditDetails.ExpirationMonth, Helpers.PossibleMonths, ...)

提供正确的 2-way 模型绑定。

【讨论】:

  • 我将尝试从我的代码中删除“选定”的内容。我只是为了在表单第一次加载时在表单上设置初始值。我的意思是如果模型的 CC Month 为 2,那么当表单自动加载时,月份下拉菜单应该指向 2。但是如果我清楚地理解你,我只需要使用你上面提到的代码,下拉菜单就会自动指向2(2-2月)。
  • 我一定会尝试并会回复您。另外,关于你说的最后一点,我想如果我保持不同的班级,我会很好地分开。所以所有与“信用卡”相关的字段都放在一个单独的视图模型“PaymentCCMV”中,并在 paymentMV 中调用。但我认为根据你我的视图模型不应该有任何其他视图模型。相反,它应该直接包含所有字段。
  • 其实PaymentCCMV本身也是一个MV。它不是域模型。只是说..
  • 好的,那很好(我只是假设它是一个数据模型)。​​
  • 我完全是初学者。原谅我的无知。您是否希望我“检查下拉元素”并在我运行代码时向您展示其中生成的 HTML。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-16
  • 1970-01-01
  • 2020-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多