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

僤鯓⒐⒋嵵緔 提交于 2019-12-11 11:00:55

问题


I've been reading through posts for two days regarding this, and still have not figured out the answer. I want to capture the DropDownList selection within my ModelView, pass this to a @Html.ActionLink, which will send it back to a specific Action within the Controller.

My ViewModel:

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

My Controller:

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
            }

My View:

            @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)

Why does the ActionLink(..., routeValues: Model.SelectedShipmentID,...) always return NULL to the Controller ? The Model.SelectedShipmentID is not updated with the DropDownList selected id. Please help as I'm running out of time on this.


回答1:


Razor code is parsed on the server before its sent to the view, so the value of your route parameter will be the initial value of SelectedShipmentID. Selecting a value from a dropdownlist does not change the url you have already rendered.

You could use javascript/jquery to handle the dropdownlist's .change() event (or the links .click() event) to update the url, however the better way to handle this is by using a form that makes a GET to your controller method

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

Note the last parameter of DropDownListFor() add a label option allowing you to post back null but not sure if this is appropriate for you.

Since your binding to a value which is int then both your model property and method parameter should be int? not string. In additiona you should change the logic in the controller so that you are not making unnecessary database calls when a valid value is passed to the method.

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

Side note: From your view model properties, I assume you wanting to display some data in the view based on the value of the selected ShipmentID. If so you should consider using ajax to post the selected value to a controller method that returns the tblShipments data based on the value, either as a partial view or as json, and update the current page, rather than doing a complete page refresh each time.



来源:https://stackoverflow.com/questions/32216842/pass-html-dropdownlist-selection-using-html-actionlink-with-viewmodel-to-contr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!