【问题标题】:Getting SelectedValue back from a DropDown in ASP.NET MVC (C#) using Entity Framework使用实体框架从 ASP.NET MVC (C#) 中的下拉菜单中获取 SelectedValue
【发布时间】:2009-12-14 00:47:49
【问题描述】:

对不起,如果这是一个重复的问题,我扫描了相关的问题并没有看到任何明显的问题。

我正在使用带有实体对象的 EditModel,以及其中的两个 SelectList。问题是,一旦我到达我的 POST 操作,无论我在浏览器上实际选择什么,两个下拉菜单的 SelectedValues 仍然是我在模型的构造函数中设置的默认值。

我的构造函数为 SelectedValues 设置了一些默认值,但它们只是 0 和“”(在下拉列表中不是有效值)。我感觉问题以某种方式围绕着这个问题,但我会提供更多细节。

这是模型的精简版:

public class UserAccountModel 
{

    public UserAccount UserAccountData { get; set; } // Entity from EF
    public SelectList Organizations { get; set; }
    public SelectList Roles { get; set; }

    public UserAccountModel() : this(null)
    {
    }


    public UserAccountModel(UserAccount obj)
    {
        UserAccountData = (obj == null) ? new UserAccount() : obj;

        // default selected value
        int orgChildId = (UserAccountData.Organization == null) ? 0 : UserAccountData.Organization.ID;
        string roleChildId = (UserAccountData.Role == null) ? "" : UserAccountData.Role.Name;

        // go get the drop down options and set up the property binding
        using (UserAccountRepository rep = new UserAccountRepository())
        {
            Organizations = new SelectList(rep.GetOrganizationOptions(), "ID", "ID", orgChildId);
            Roles = new SelectList(rep.GetRoleOptions(), "ID", "Name", roleChildId);
        }
    }

    public void UpdateModel()
    {
        UserAccountData.Organization = Organizations.SelectedValue as Organization;
        UserAccountData.Role = Roles.SelectedValue as Role;
    }
}

这是视图的下拉部分:

                <div class="field">
                <label for="ID">Organization:</label>
                <%= Html.DropDownList("ID", Model.Organizations) %>
            </div>

            <div class="field">
                <label for="Name">Role:</label>
                <%= Html.DropDownList("Name", Model.Roles) %>
            </div>

我可能在这里做了一些愚蠢而明显的事情。使用 ViewData 字典时,这些示例更加直接,但我找不到太多尝试对 SelectLists 使用直接模型绑定的示例。

非常感谢任何帮助!

克里斯

【问题讨论】:

  • 控制器代码是什么样的?
  • 您能否发布一些 UserAccountData 结构的代码,如果您绑定到 ViewModel,那么我认为选择列表的名称应该是“UserAccountData.ID”和“UserAccountData.Name”,我不确定因为我不知道 UserAccountData 的结构
  • UserAccountData 是一个实体,其代码由实体框架生成。但是,我应该提到的另一条信息是组织和角色是数据库中 UserAccount 表中的外键。添加用户帐户时,我希望能够从数据库中的现有选择中选择组织和角色。上面模型上的 UpdateModel() 方法用于将选定的组织和角色添加到 UserAccountData
  • 不确定控制器代码添加了什么。我只是在调用 POST 操作时设置了一个断点,并且我期望模型中 SelectLists 的 SelectedValue 值根据下拉列表中的选择进行设置。如果不是这种情况,那么看起来我只需将 SelectedValues(名称和 ID)添加为模型上的显式属性。

标签: c# asp.net-mvc drop-down-menu modelbinders selectedvalue


【解决方案1】:

选择元素只回发被选择它的实际值。在这种情况下,参数将作为 ID(组织)和名称(角色)在服务器/控制器处接收回。您用于更新操作的模型应该包含这些作为属性,或者您的控制器操作应该直接接受它们作为参数。模型上的列表不会被重新填充 - 并且名称在任何情况下都不匹配。

通过添加修改您的模型:

public int ID { get; set; }
public string Name { get; set; }

控制器动作为:

public ActionResult Update( UserAccountModel userAccount )
{
    ...
}

请注意,如果出现验证错误,您需要重新填充 SelectList 属性(重构菜单)。

【讨论】:

  • 那么,模型上的 SelectList 属性没有得到更新?我希望看到 SelectList 上的 SelectedValue 使用视图中的实际选定值进行更新,然后我会将该值从 SelectList 中拉出并更新我的 UserAccountData。如果不是这种情况,那么我会听取您的建议并添加要更新的显式属性。
  • 没有。由于表单 post 中仅返回选定的值,因此它甚至没有用于重新填充选择列表的数据。我总是为枚举(我使用 IEnumerable)和我的模型中的选定值添加属性。
  • 我唯一的问题是我在存储库后面使用实体框架。我实际上是在查询要在 SelectLists 中列出的完整对象,因为它们非常小。结果,我已经从数据库中获得了整个对象。然后您是否在选择列表中查找 SelectedValue ID 以获取完整数据?
  • 如果你有缓存列表,那么是的,否则你需要重新查询。如果要重构整个对象,则需要将选择列表中每个对象的所有数据放在表单上,​​然后再将其发回。模型绑定器唯一需要处理的是发布的数据。如果您使用缓存,也许还使用自定义模型绑定器,那么您可以从那里重构整个列表。我会说这是一种优化,我可能会重新查询,直到我知道这将是一个性能问题。
  • 自定义绑定可能是一个不错的选择(这也是一位同事刚刚向我提到的)。我想我会玩一下,否则我会选择你的更简单的上面的选项。再次感谢!
【解决方案2】:

您只是忘记了 ID 属性的导航路径 :)

<%= Html.DropDownList("Organization.ID", Model.Organizations) %>

【讨论】:

  • 我觉得可能也这么简单,但是我已经确定了路径,我认为它是正确的。 “Organizations”(复数)实际上是“Organization”对象的 SelectList,因此 ID 不作为 Organizations 的成员存在。我想我需要将 Organizations.SelectedValue 转换为组织类型,但我不确定它在视图中如何工作(如果有的话)。不过,我愿意接受建议,因为在我看来,无法以某种方式正确设置 SelectedValue 是不对的!
猜你喜欢
  • 2015-09-17
  • 1970-01-01
  • 2020-05-26
  • 1970-01-01
  • 2012-07-22
  • 2015-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多