Emre Sert
Emre Sert

Reputation: 330

DropdownList is giving a null value to controller calling model

I am a student developer in ASP.NET. I have a question which i did not find a solution about it. I can build a form for my controller. i am taking a value from my input objects but i am not taking value from dropdown list to my controller. It gives null value on my controller. Could you help me about where i made a mistake?

My View Model :

public class CountryViewModel
{
    public IEnumerable<Country> CountryList { get; set; }
    public Country Country;
}

My controller :

 public ActionResult Index()
    {

        var model = new CountryViewModel()
        {
            CountryList = db.Country.ToList()
        };
        return View(model);
    }
    [HttpPost]
    public ActionResult Index(string timeForCheckedOut,CountryViewModel cvModel)
    {

        return View();
    }

my index.cshtml:

   @model PenaltyCalculation.Models.ViewModel.CountryViewModel

<form class="" style="margin-top:10%;" action="/" method="post">
    <div class="form-group">
        <label>Check out date of the Book</label>
        <input class="form-control" type="date" name="timeForCheckedOut">
    </div>
    <div class="form-group">
        <label>Choose a country</label>
        @Html.DropDownListFor(m=>m.Country.countryId,new SelectList(Model.CountryList,"countryId","countryName"),new {@class="form-control" })
    </div>
    <button type="submit" class="btn btn-primary">Calculate</button>
</form>

My Country Model:

 public partial class Country
    {
        public int countryId { get; set; }
        public string countryName { get; set; }          
    }

Upvotes: 1

Views: 79

Answers (2)

Patrick Mcvay
Patrick Mcvay

Reputation: 2281

Option #1:

You just need to put the { get; set; } on the end of Country in your CountryViewModel. This will allow you to set the countryId value, but the name will not be set. You will have to look that up from your db if you need that also.

public class CountryViewModel
{
    public IEnumerable<Country> CountryList { get; set; }
    public Country Country { get; set; }
}

Option #2

This is what I would do. Remake your CountryViewModel to actually represent your View's Model.

public class CountryViewModel
{
    public int CountryID { get; set; }
    public DateTime TimeForCheckedOut { get; set; }
}

Then update your controller.

    // Simulating a db
    private List<Country> Countries;

    public HomeController()
    {
        // Initializing sample data
        Countries = new List<Country>();

        Countries.Add(new Country() { countryId = 1, countryName = "USA" });
        Countries.Add(new Country() { countryId = 2, countryName = "England" });
        Countries.Add(new Country() { countryId = 3, countryName = "Japan" });
        Countries.Add(new Country() { countryId = 4, countryName = "China" });
    }

    public ActionResult Index()
    {
        // I prefer using the ViewData Dictionary for my selectlists
        ViewData["CountrySelectList"] = new SelectList(Countries, "countryId", "countryName");

        return View();
    }

    [HttpPost]
    public ActionResult Index(CountryViewModel cvModel)
    {
        var country = Countries.First(c => c.countryId == cvModel.CountryId);
        // Do Stuff Like Saving and Updating

        ViewData["CountrySelectList"] = new SelectList(Countries, "countryId", "countryName", cvModel.CountryId);
        return View(cvModel);
    }

And Finally update your View

@model PenaltyCalculation.Models.ViewModel.CountryViewModel

<form class="" style="margin-top:10%;" action="/" method="post">
    <div class="form-group">
        <label>Check out date of the Book</label>
        <input class="form-control" type="date" name="timeForCheckedOut">
    </div>
    <div class="form-group">
        <label>Choose a country</label>

        @Html.DropDownListFor(m => m.CountryId, (SelectList)ViewBag.CountrySelectList, new { @class = "form-control" })
    </div>
    <button type="submit" class="btn btn-primary">Calculate</button>
</form>

Upvotes: 2

LP13
LP13

Reputation: 34079

public class CountryController : Controller
{
    // GET: Country
    public ActionResult Index()
    {
        var model = new CountryViewModel()
        {
            CountryList = GetCountries()
        };

        return View(model);
    }

    [HttpPost]
    public ActionResult Index(CountryViewModel model)
    {
        model.CountryList = GetCountries();
        return View(model);
    }

    private IEnumerable<Country> GetCountries()
    {
        return new Country[]
            {
                new Country()
                {
                    CountryID = 1,
                    CountryName = "USA"
                },
                new Country()
                {
                    CountryID = 2,
                    CountryName = "Mexico"
                },
            };
    }
}

public class CountryViewModel
{
    public IEnumerable<Country> CountryList { get; set; }
    public int CountryID { get; set; }
    public DateTime? TimeForCheckedOut { get; set; }
}

public partial class Country
{
    public int CountryID { get; set; }
    public string CountryName { get; set; }
}

<form class="" style="margin-top:10%;" action="/Country/Index" method="post">
    <div class="form-group">
        <label>Check out date of the Book</label>
        <input class="form-control" type="date" name="TimeForCheckedOut">
    </div>
    <div class="form-group">
        <label>Choose a country</label>
        @Html.DropDownListFor(m => m.CountryID, new SelectList(Model.CountryList, "CountryID", "CountryName"), new { @class = "form-control" })        
    </div>
    <button type="submit" class="btn btn-primary">Calculate</button>
</form>

This is working for me

Make sure CountryID has getter and setter. Also in C# public property name starts with Capital letter (by convention)

I would also suggest, don't bind Country entity directly to view. You may want to create CountryModel

Upvotes: 0

Related Questions