为什么ListBox不选择项目,但ListBox是?

Rog*_*ers 30 asp.net-mvc listbox

我在视图中有以下代码:

<%= Html.ListBoxFor(c => c.Project.Categories,
        new MultiSelectList(Model.Categories, "Id", "Name", new List<int> { 1, 2 }))%>

<%= Html.ListBox("MultiSelectList", 
        new MultiSelectList(Model.Categories, "Id", "Name", new List<int> { 1, 2 }))%>
Run Code Online (Sandbox Code Playgroud)

唯一的区别是第一个帮助器是强类型的(ListBoxFor),并且它无法显示所选项(1,2),即使项目出现在列表中,等等.更简单的ListBox正在按预期工作.

我显然在这里遗漏了一些东西.我可以使用第二种方法,但这真的让我烦恼,我想弄清楚.

作为参考,我的模型是:

public class ProjectEditModel
{
    public Project Project { get; set; }
    public IEnumerable<Project> Projects { get; set; }
    public IEnumerable<Client> Clients { get; set; }
    public IEnumerable<Category> Categories { get; set; }
    public IEnumerable<Tag> Tags { get; set; }
    public ProjectSlide SelectedSlide { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

更新

我刚刚将ListBox名称更改为Project.Categories(匹配我的模型),现在它已选择FAILS来选择项目.

<%= Html.ListBox("Project.Categories",
        new MultiSelectList(Model.Categories, "Id", "Name", new List<int> { 1, 2 }))%>
Run Code Online (Sandbox Code Playgroud)

我显然不理解这里发生的魔法.

更新2

好吧,这纯粹是命名,例如,这有效......

<%= Html.ListBox("Project_Tags",
new MultiSelectList(Model.Tags, "Id", "Name", Model.Project.Tags.Select(t => t.Id)))%>
Run Code Online (Sandbox Code Playgroud)

...因为字段名称是Project_Tags,而不是Project.Tags,事实上,除了Tags或Project.Tags之外的任何东西都可以使用.我不明白为什么这会导致一个问题(除了它与实体名称相匹配),而且我还不够好,能够挖掘并找出答案.

Oli*_*ier 25

我自己偶然发现了这个问题,最后我意识到这个问题是一个命名约定.

您不能将包含SelectList或MultiSelectList的ViewBag或ViewData属性命名为包含所选项的属性模型的相同名称.至少不是你使用ListBoxFor或DropDownListFor帮助器.

这是一个例子:

    public class Person
    {
          public List<int> Cars { get; set; }
    }

    [HttpGet]
    public ActionResult Create()
    {
          //wont work
          ViewBag.Cars = new SelectList(carsList, "CarId", "Name"); 

          //will work due to different name than the property.
          ViewBag.CarsList = new SelectList(carsList, "CarId", "Name"); 

          return View();
    }

    //View
    @Html.ListBoxFor(model => model.Cars, ViewBag.CarsList as SelectList)
Run Code Online (Sandbox Code Playgroud)

我确信还有很多其他方法可以做到这一点,但它解决了我的问题,希望它能帮助别人!


Ale*_*ite 1

虽然这不是您主要问题的答案,但值得注意的是,当 MVC 生成名称时,它会将 Project.Tags 之类的内容转换为 Project_Tags,并用下划线替换句点。

这样做的原因是,元素 ID 中的句点看起来像一个名为 Project 的元素,其中包含 CSS 标签类。显然是一件坏事,因此翻译为下划线以保持行为可预测。

在你的第一个例子中,

<%= Html.ListBoxFor(c => c.Project.Categories,
    new MultiSelectList(Model.Categories, "Id", "Name", new List<int> { 1, 2 }))%>
Run Code Online (Sandbox Code Playgroud)

列表框正在尝试绑定到已提供给页面的强类型模型的 Model.Project.Categories(使用 lambda 表示法)。我不确定 ListBoxFor 中的第二个参数在做什么。

传递到页面的模型是什么?