在 Razor 视图的 @html.ActionLink 中,我们如何传递下拉列表的值?

In a Razor View's @html.ActionLink, how do we pass the value of a dropdown list?

所以我想做的是我有一个角色数据库 table,我想在下拉列表中显示它,并将值发送到不同的控制器函数。但是,当我尝试这样做时,我没有收到从下拉列表中选择的新角色的值,而是收到了之前在我的模型中的值。 这是我的 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");
}

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

问题是,在没有 JavaScript 的情况下,您无法将下拉列表的选定值动态附加到您的操作 link。

我认为更优雅的方法是将下拉菜单和操作按钮放在 <form> 中。这样,该方法也可以是 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 制作第二个 <form>,或者在相同的表单中也制作一个提交按钮,并分别给按钮一个 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>