【问题标题】:In a Razor View's @html.ActionLink, how do we pass the value of a dropdown list?在 Razor View 的@html.ActionLink 中,我们如何传递下拉列表的值?
【发布时间】:2021-07-08 23:53:00
【问题描述】:

所以我想要做的是我有一个角色数据库表,我想在下拉列表中显示,并将值发送到不同的控制器函数。但是,当我尝试执行此操作时,我没有收到从下拉列表中选择的新角色的值,而是收到之前在我的模型中的值。 这是我的 CSHTML 代码:

@model IEnumerable<OnlineStoreData.Model.User>
<h4>List of Users: </h4>

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.UserName)
        </th>
        <th></th>
    </tr>

@foreach (var user in Model) {
    if (user.Role.RoleName.TrimEnd(' ') == "User")
    {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => user.UserName)
        </td>
        <td>
            @Html.DropDownListFor(modelItem => user.Role.RoleName, new SelectList(ViewBag.RoleList)) //Here I need to select a new Role, for example "Admin"
            @Html.ActionLink("Promote", "Promote", new { id = user.UserId, role = user.Role.RoleName }) |  
            @Html.ActionLink("Delete", "Delete", new { id = user.UserId })
        </td>
    </tr>
    }
}

</table>

这是我的控制器的代码

public ActionResult ManageUsers()
{
    ViewBag.RoleList = storeDBEntities.Roles.Select(role => role.RoleName).ToList();
    return View(storeDBEntities.Users.ToList());
}

public ActionResult Promote(int id, string role)
{
    //Here I should get  the new role selected in the dropdown list, but I keep getting "User", which is the old role. 
    User toPromUser = storeDBEntities.Users.Find(id);
    Role newRole = storeDBEntities.Roles.FirstOrDefault(r => r.RoleName == role);
    if(toPromUser != null && newRole != null)
    {
        toPromUser.Role = newRole;
        toPromUser.UserRole = newRole.RoleId;
        storeDBEntities.SaveChanges();
    }
    return RedirectToAction("ManageUsers", "Users");
}

我不确定我应该如何解决这个问题以使代码执行预期的操作。谢谢。

【问题讨论】:

    标签: asp.net-mvc razor dropdown


    【解决方案1】:

    问题是,如果没有 JavaScript,您无法将下拉列表的选定值动态附加到您的操作链接。

    我认为更优雅的方法是将下拉和操作按钮放在&lt;form&gt; 中。这样,该方法也可以是post,这在某种程度上更好,因为get 操作不应该操纵数据。

    <td>
        <form method="post" action="@Url.Action("Promote", new { id = user.UserId })">
            @Html.DropDownList("role", new SelectList(ViewBag.RoleList))
            <button type="submit">Promote</button>
            |  
            @Html.ActionLink("Delete", "Delete", new { id = user.UserId })
        </form>
    </td>
    

    请注意,下拉列表的name 应与控制器的role 参数的名称匹配。


    当它起作用时,您可以将[HttpPost] 属性添加到您的Promote 操作中,以说明此方法会改变一些东西。

    对于您的删除操作,您可以执行类似的操作。使用不同的 URL 创建第二个 &lt;form&gt;,或者也将其设置为提交按钮,以相同的形式,并为每个按钮分配 namevalue。 您单击的按钮的值将发送到服务器 - 请注意,我更改了表单操作 URL:

    <td>
        <form method="post" action="@Url.Action("Update", new { id = user.UserId })">
            @Html.DropDownList("role", new SelectList(ViewBag.RoleList))
            <button type="submit" name="operation" value="promote">Promote</button>
            | 
            <button type="submit" name="operation" value="delete">Delete</button>
        </form>
    </td>
    

    然后决定在控制器中做什么:

    [HttpPost]
    public ActionResult Update(int id, string operation, string role)
    {
        ...
    

    最后,您可能想要一个关于删除操作的确认消息,可以这样做:

    <button type="submit" name="operation" value="delete" onclick="return confirm('Do you really want to delete this user?');">Delete</button>
    

    【讨论】:

    • 您好,这非常有效。非常感谢你。我从来没有想过使用表格,因为我已经在精神上将表格和表格分开了,并且从未将它们一起使用过。
    • 不客气,很高兴它成功了! MVC 的巧妙之处在于控制器并不真正关心参数值的来源,并且您不再有 ASPX 的旧限制,您在页面上只能有一个表单。干杯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 2017-03-07
    • 1970-01-01
    • 2018-11-27
    • 2021-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多