Search code examples
asp.net-mvc

Correct way to display a list in a dropdown using mvc


I know there are a lot of similar question here but none seem quite the same as mine.

In my View:

@model LocalInformedMotionServer.Models.FeedData
@Html.DropDownList("Premise", Model.LoadUp("key"), new { @style = "width: 218px;height:35px;" })

In my controller:

public class CloudController  : Controller
{
    public IEnumerable<wsCommon.Premise> Premises { get; set; }
    public ActionResult Feed(string key)
    {
        var feedData = new FeedData();
       Premises= feedData.LoadUp(key);
        return View(feedData);
    }    
}

In my Model:

public class FeedData
{
    public IEnumerable<wsCommon.Premise> LoadUp(string saltKey)
    {
        Premises premises = new InformedBiz.Premises();
        return premises.GetPremises(saltKey);
    }
}

It errors because the variable:

   "key" 

in this call:

  Model.LoadUp("key")

is being read in as'null' in my controller method.

Of course as this is all new to me I could be doing this all wrong..

ADDITIONAL:

In my CloudController Class I have this:

 public class CloudController  : Controller
    {
    public ActionResult Feed(string saltKey)
    {
        var feedData = new FeedData();
        feedData.LoadUp(saltKey); 
        return View(feedData);
    }

    public ActionResult Index()
    {
        return View();
    }
    public ActionResult LogIn()
    {
        return View();
    }
}

Solution

  • You have not posted the properties of your FeedData model but assuming it contains a property which is typeof Premise and you want to be able to select a Premise from a collection, then using a view model that represents what you want to display/edit is the recommended approach (refer View Model Design And Use In Razor Views and What is ViewModel in MVC?)

    You view model might look like

    public class FeedDataVM
    {
      .....
      [Display(Name = "Premise")]
      [Required(ErrorMessage = "Please select a Premise")]
      public int? SelectedPremise { get; set; }
      ....
      public SelectList PremiseList { get; set; }
    }
    

    and in your controller (not sure what saltKey is for?)

    public ActionResult Feed(string saltKey)
    {
      FeedDataVM model = new FeedDataVM();
      IEnumerable<Premise> premises = // get the collection of premise objects from your repository
      // assuming you want to display the name property of premise, but post back the key property
      model.PremiseList = new SelectList(premises, "key", "name");
      return View(model);
    }
    

    View

    @model FeedDataVM
    @using(Html.BeginForm())
    {
      ....
      @Html.LabelFor(m => m.SelectedPremise)
      @Html.DropDownListFor(m => m.SelectedPremise, Model.PremiseList, "-Please select")
      @Html.ValidationMessageFor(m => m.SelectedPremise)
      ....
      <input type="submit" value="Save" />
    }
    

    and the POST method

    public ActionResult Feed(FeedDataVM model)
    {
      // model.SelectedPremise contains the value of the selected option as defined by the key property of Premise
    }
    

    Side note: Your FeedData model contains a method to retrieve a collection of Premise which appears to be calling another service. You should avoid this type of design which makes it difficult to debug and unit test. Your controller is responsible for initializing/getting you data models and view models and for populating/mapping their properties.