【问题标题】:Using DropDownList(For) with model binding on nested class在嵌套类上使用带有模型绑定的 DropDownList(For)
【发布时间】:2014-08-08 00:43:20
【问题描述】:

我在我的应用程序中严重依赖 EditorTemplates,但我遇到了一个我似乎无法解决的问题,而没有离开 EditorTemplates 的下拉列表。

考虑这个(视图)模型:

public class CreateStudentViewModel
{
    public DropDownList StudentTypes { get; set; }
    public CreateStudent Command { get; set; }
}

public class DropDownList {
    public string SelectedValue { get; set; }
    public IList<SelectListItem> Items { get; set; }
}

public class CreateStudent {
    public string Name { get; set; }
    public int StudentTypeId { get; set; }
}

我使用它为前端用户提供一种设置学生类型的方法,这是通过以下 EditorTemplate 完成的:

@model DropDownList
<div class="form-group@(Html.ValidationErrorFor(m => m.SelectedValue, " has-error"))">
    @Html.LabelFor(m => m)
    @Html.DropDownListFor(m => m.SelectedValue, Model.Items)
    @Html.ValidationMessageFor(m => m.SelectedValue, null)
</div>

并在我看来使用:

@Html.EditorFor(m => m.StudentTypes)

现在这个 EditorTemplate 绑定到 DropDownList 上的 StudentTypes.SelectedValue,这在某些情况下很好 - 但我需要在这里将它绑定到我的 Model.Command.StudentTypeId

我知道我可以将所有这些代码直接移动到视图并直接绑定它,而不是将其放在 EditorTemplate 中,但我会尽量避免这种情况。

理想情况下,我正在考虑扩展 EditorFor 以提供如下方式:

@Html.EditorFor(m =&gt; m.StudentTypes, new { selectedValue = Model.Command.StudentTypeId });

但我似乎无法将其翻译为:

@Html.DropDownList(@ViewBag.selectedValue.ToString(), Model.Items);

因为这只是将值 (int) 作为字段名称。欢迎任何建议! :-)

【问题讨论】:

  • 根据我的经验,razor 中的 html.dropdownlist 一直很挑剔。我发现自己经常不得不将所有内容都压缩到一个复杂的视图模型中,以使其以我需要的方式绑定,尤其是对于复杂的实体。

标签: c# asp.net-mvc model-binding html.dropdownlistfor


【解决方案1】:

您的主要问题是将下拉列表封装在一个类中,以便依赖 C# 类型编辑器模板约定。相反,只需直接使用您的模型并使用UIHint 告诉 Razor 使用特定模板。这是我使用的简化版本:

查看模型

[UIHint("Choice")]
public int SelectedFoo { get; set; }

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

Views\Shared\EditorTemplates\Choice.cshtml

@{
    var choices = ViewData["choices"] as IEnumerable<SelectListItem> ?? new List<SelectListItem>();

    if (typeof(System.Collections.IEnumerable).IsAssignableFrom(ViewData.ModelMetadata.ModelType) && ViewData.ModelMetadata.ModelType != typeof(string))
    {
        @Html.ListBox("", choices)
    }
    else
    {
        @Html.DropDownList("", choices)
    }
}

查看

@Html.EditorFor(m => m.SelectedFoo, new { choices = Model.FooChoices })

如果不明显,编辑器模板中的条件会确定属性是值还是列表类型,并分别使用下拉列表控件或列表框控件。

【讨论】:

  • 有趣,我会试试这个。我可以使用 EditorFor 上的字符串直接指向模板,而不是使用 UIHint 注释?
  • 谢谢,这是为我做的 :-) 你为什么建议使用 ListBox 和 DropDownList? (仅供参考)
  • 所以有一个模板可以涵盖这两种情况。我不想关心我是期待一个选定的值还是多个选定的值。我只是将属性提供给模板,如果它需要多选,它会得到一个。
  • 太好了 :-) 再次感谢!
猜你喜欢
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-28
相关资源
最近更新 更多