使用 @Html.ActionLink 和 ViewModel 将 @Html.DropDownList 选择传递给控制器

Pass @Html.DropDownList selection using @Html.ActionLink with ViewModel to Controller

这两天看了帖子,还没找到答案。我想在我的 ModelView 中捕获 DropDownList 选择,将其传递给 @Html.ActionLink,这会将其发送回控制器中的特定操作。

我的视图模型:

    public class ViewModelShipments
    {
        public ViewModelShipments()
        {
            tblShipments = new tblShipments();
        }
        public tblShipments tblShipments;
        public IEnumerable<SelectListItem> ShipmentIDsList;
        public string SelectedShipmentID; 
    }

我的控制器:

public ActionResult SelShipment(string SelectedShipmentID)//for ShipmentID change via DropDownList
        {
            int id = db.tblShipments.Max(p => p.ShipmentID); // find last ShipmentID
            if (SelectedShipmentID != null)
            {
                id = Int32.Parse(SelectedShipmentID);//convert text to int
            }

我的看法:

            @Html.DropDownListFor(expression: model=>model.SelectedShipmentID,selectList: Model.ShipmentIDsList) @* render DropDownList object*@
            @Model.SelectedShipmentID @* display value of SelectedShipmentID *@

            <!-- Upon Click, send selected ID to controller --> 
            <!-- the ActionLink is working, but the routeValues: always contain NULL -->
            @Html.ActionLink(linkText: "Submit", actionName: "SelShipment", controllerName: "Shipment", routeValues: Model.SelectedShipmentID, htmlAttributes: null)

为什么控制器的 ActionLink(..., routeValues: Model.SelectedShipmentID,...) 总是 return NULL? Model.SelectedShipmentID 未使用 DropDownList 选定的 ID 进行更新。请帮忙,因为我运行没时间了。

Razor 代码在发送到视图之前在服务器上进行解析,因此您的路由参数的值将是 SelectedShipmentID 的初始值。从下拉列表中选择一个值不会更改您已经呈现的 url。

您可以使用 javascript/jquery 来处理下拉列表的 .change() 事件(或链接 .click() 事件)来更新 url,但是更好的处理方式是通过使用对控制器方法进行 GET 的表单

@model ViewModelShipments
@using (Html.BeginForm("SelShipment", "Shipment", FormMethod.Get))
{
  @Html.DropDownListFor(m => m.SelectedShipmentID, Model.ShipmentIDsList, "-Please select-")
  <input type="submit" />
}

注意 DropDownListFor() 的最后一个参数添加一个标签选项,允许您 post 返回 null 但不确定这是否适合您。

由于您绑定的值是 int,因此您的模型 属性 和方法参数都应该是 int? 而不是 string。此外,您应该更改控制器中的逻辑,以便在将有效值传递给方法时不会进行不必要的数据库调用。

public ActionResult SelShipment(int? SelectedShipmentID)
{
  if (!SelectedShipmentID.HasValue)
  {
    // only necessary to call database if SelectedShipmentID is null
    SelectedShipmentID = db.tblShipments.Max(p => p.ShipmentID)
  }
  ....
}

旁注:根据您的视图模型属性,我假设您希望根据所选 ShipmentID 的值在视图中显示一些数据。如果是这样,您应该考虑使用 ajax 到 post 将所选值用于控制器方法,该方法 returns tblShipments 数据基于该值,作为局部视图或 json,并更新当前页面,而不是每次都进行完整的页面刷新。