ViewModel getting null values in action method

后端 未结 2 1692
北海茫月
北海茫月 2020-12-10 18:49

I am using a ViewModel to retrieve entered data in controller action. But the ViewModel is getting empty values in it\'s properties. I am creating one partial view

相关标签:
2条回答
  • 2020-12-10 19:03

    You cannot bind a dropdownlist to a collection of complex objects - in your case IEnumerable<tblCurrentLocation> and IEnumerable<tblStream>

    A <select> tag only posts back a single value (the value of the selected option) so in the POST method the DefaultModelBinder is attempting to so testName.tblCurrentLocations = "1" (assuming the value of the selected option is 1) which of course fails and the property is set to null

    You need a view model containing properties that you want to bind to (and ideally will include the SelectList's used by the DropDownListFor() helper)

    public class LookUpViewModel
    {
      [Display(Name = "Location")]
      [Required(ErrorMessage = "Please select a location")]
      public int SelectedLocation { get; set; }
      [Display(Name = "Stream")]
      [Required(ErrorMessage = "Please select a stream")]
      public int SelectedStream { get; set; }
      public SelectList LocationList { get; set; }
      public SelectList StreamList { get; set; }
    }
    

    Then in the view

    @Html.LabelFor(m => m.SelectedLocation)
    @Html.DropDownListFor(m => m.SelectedLocation, Model.LocationList, "-Please select-")
    @Html.ValidationMessageFor(m => m.SelectedLocation)
    
    @Html.LabelFor(m => m.SelectedStream)
    @Html.DropDownListFor(m => m.SelectedStream, Model.StreamList, "-Please select-")
    @Html.ValidationMessageFor(m => m.SelectedStream)
    

    and in the controller

    public ActionResult Edit()
    {
      LookUpViewModel model = new LookUpViewModel();
      ConfigureViewModel(model);
      return View(model);
    }
    
    [HttpPost]
    public ActionResult Edit(LookUpViewModel model)
    {
      if (!ModelState.IsValid)
      {
        ConfigureViewModel(model);
        return View(model);
      }
      // model.SelectedLocation will contain the value of the selected location
      // save and redirect
    }
    
    private void ConfigureViewModel(LookUpViewModel model)
    {
      // populate your select lists
      var locations = from o in rosterManagementContext.tblCurrentLocations select o;
      model.LocationList = new SelectList(locations, "LocationId", "Location");
      .... // ditto for streams
    }
    

    Note as also indicated in Maximilian's answer, your view model should only contain properties your need for the view. Your controller is responsible for populating the values. A view model should never make a call to a database - it should not even be aware that one exists.

    0 讨论(0)
  • 2020-12-10 19:20

    This answer will not solve your problem directly, but first of all I recommend you to outsource the filling of the ViewModel at least to the controller (Because otherwise it will recreate the DBContext every time the constructor is called). A ViewModel should only contain data - no logic. And secoundly I would use the DBContext in an Using statement

    ViewModel:

    public class LookUpViewModel
        {    
            [Required]
            public virtual IEnumerable<tblCurrentLocation> tblCurrentLocations { get; set; }
    
            [Required]
            public virtual IEnumerable<tblStream> tblStreams {  get;  set; }
    

    Controller:

    public ActionResult Foo()
    {
        LookUpViewModel ViewModel = new LookUpViewModel();
        using(RosterManagementEntities rosterManagementContext = new RosterManagementEntities())
        {
            ViewModel.tblCurrentLocations = from o in rosterManagementContext.tblCurrentLocations select o;
            ViewModel.tblStreams = from o in rosterManagementContext.tblStreams select o; 
        }
    
        return View(ViewModel);
    }
    
    0 讨论(0)
提交回复
热议问题