在 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>
,或者在相同的表单中也制作一个提交按钮,并分别给按钮一个 name
和 value
。
您单击的按钮的值将被发送到服务器 - 请注意,我更改了表单操作 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>
所以我想做的是我有一个角色数据库 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>
,或者在相同的表单中也制作一个提交按钮,并分别给按钮一个 name
和 value
。
您单击的按钮的值将被发送到服务器 - 请注意,我更改了表单操作 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>