【问题标题】:MVC 5 - MultiSelectList, Binding values with Model "SelectList" propertyMVC 5 - MultiSelectList,使用模型“SelectList”属性绑定值
【发布时间】:2014-08-06 06:00:58
【问题描述】:

在我的 MVC 项目中,我遇到了将 MultiSelectLists 与我的模型属性绑定的问题。虽然我可以通过 FormCollection 对象获取值,但这些只是 Selected ID。

以下是我的模型类,它代表一个帖子。

public class PostModel
{
    [Required(ErrorMessage = "Id is a required field")]
    public int Id { get; set; }

    [Required(ErrorMessage = "Post Title is required")]
    [StringLength(500)]
    public string Title { get; set; }

    .......

    public SelectList UnassignedTags { get; set; }
    public SelectList AssignedTags { get; set; }
}

请注意,这只是一个模型类,并且有两个附加属性(UnassignedTags 和 AssignedTags),仅用于在屏幕上显示它们并保持调用之间的值绑定。

一个帖子可以标记多个标签。在我的视图中,我想要两个多选列表。一个用于保存未分配的标签(文本和值),另一个用于保存已分配的标签(文本和值)。

在我看来,我使用以下代码显示这些列表的多选列表。

@Html.ListBox("UnassignedTagss", Model.UnassignedTags, new { @class = "form-control" })

@Html.ListBox("AssignedTagss", Model.AssignedTags, new { @class = "form-control" })

当我在屏幕上加载记录时一切正常。

加载后,我让用户通过 javascript 在列表之间移动项目。

当表单被发回以进行版本时,问题就出现了。我无法将 Listbox 值与我的模型属性绑定。

以下是我显示/编辑帖子记录的操作方法。

public ActionResult PostDtls(int postId)
{
    …..
}

[HttpPost]
public ActionResult PostDtls(PostModel post, FormCollection collection)
{
    …….
}

有什么方法可以将 ListBox 项(无论是否选择)绑定到我的模型 SelectList 属性,即 UnAssignedTags 和 AssignedTags ?

目前,我正在通过 JQuery 选择 ListBox 的所有项目,然后再将表单发送回服务器。这样,我在 FormCollection 对象中得到逗号分隔的 Id。但是,问题在于,如果由于无效的 ModelState 而必须向用户重新显示视图,则必须根据 FormCollection 对象中可用的 Id 从数据库中获取标签。 我知道上述解决方案很糟糕。而且我需要知道实现这一要求的好方法。

【问题讨论】:

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


    【解决方案1】:

    我不确定您为什么采用这种方法。您需要的第一件事是视图模型中的 2 个附加属性(我假设值类型是 int

    public int[] SelectedUnassignedTags { get; set; }
    public int[] SelectedAssignedTags  { get; set; }
    

    然后如下创建DropDownLists

    @Html.ListBoxFor(m => m.SelectedUnassignedTags, Model.UnassignedTags, ...)
    @Html.ListBoxFor(m => m.SelectedUnassignedTags, Model.UnassignedTags, ...)
    

    在回发时,SelectedUnassignedTagsSelectedAssignedTags 将包含已在相应列表框中选择的值,例如,如果您选择了这两个选项

    <option value="2">Item No 2</option>
    <option value="4">Item No 4</option>
    

    那么SelectedUnassignedTags 将是一个包含 2 和 4 的数组

    在你的发布方法中(看不到任何需要FormCollection

    public ActionResult PostDtls(PostModel post)
    {
      if (!ModelState.IsValid())
      {
        // Repopulate you select lists (as you would have done in the get method)
        return View(post);
      }
    }
    

    尝试在 javascript 中构造所有必要的选项值、关联文本和选定状态并回发那么多额外数据,然后在 post 方法中重构它们可能比数据库调用更昂贵(当然,您可以随时缓存它们以避免调用数据库)

    【讨论】:

    • 感谢斯蒂芬的回复。正如建议的那样,我可以通过我的模型 int[] 属性获取 Id。然而,令我不安的是,每次提交表单时,我都只有已分配/未分配的 ID(可能与最初加载的 ID 不同)并且没有选项文本。因此,每次提交表单时,我都必须根据这些 ID 从数据库中获取详细信息(标记显示文本)。那正确吗 ?或者我在这里遗漏了一些东西
    • 是的,这是更好的方法。虽然可以使用 javascript 回发每个选项的 ID 值、文本值和选定状态,但这(除了非常复杂的代码之外)可能比从数据库中获取要慢得多。它只有在您有验证错误时才适用,并且通过正确使用属性,它都可以在客户端处理,因此模型应该很少是无效的。如果其数据相当静态,请使用MemoryCacheSession 以避免调用数据库。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    • 1970-01-01
    • 2018-01-02
    • 1970-01-01
    • 2014-07-21
    • 1970-01-01
    相关资源
    最近更新 更多