9

I'm trying to populate a DropDownList and to get the selected value when I submit the form:

Here is my model :

public class Book
{
    public Book()
    {
        this.Clients = new List<Client>();
    }

    public int Id { get; set; }
    public string JId { get; set; }
    public string Name { get; set; }
    public string CompanyId { get; set; }
    public virtual Company Company { get; set; }
    public virtual ICollection<Client> Clients { get; set; }
}

My Controllers :

    [Authorize]
    public ActionResult Action()
    {
        var books = GetBooks();
        ViewBag.Books = new SelectList(books);
        return View();
    }

    [Authorize]
    [HttpPost]
    public ActionResult Action(Book book)
    {
        if (ValidateFields()
        {
            var data = GetDatasAboutBookSelected(book);
            ViewBag.Data = data;
            return View();
        }
        return View();
    }

My Form :

@using (Html.BeginForm("Journaux","Company"))
{
<table>
    <tr>
        <td>
            @Html.DropDownList("book", (SelectList)ViewBag.Books)
        </td>
    </tr>
    <tr>
        <td>
            <input type="submit" value="Search">
        </td>
    </tr>
</table>
}

When I click, the parameter 'book' in the Action is always null. What am I doing wrong?

Azzedine Hassaini
  • 331
  • 4
  • 5
  • 16

2 Answers2

15

In HTML a dropdown box sends only simple scalar values. In your case that would be the id of the selected book:

@Html.DropDownList("selectedBookId", (SelectList)ViewBag.Books)

and then adapt your controller action so that you will retrieve the book from the id that gets passed to your controller action:

[Authorize]
[HttpPost]
public ActionResult Action(string selectedBookId)
{
    if (ValidateFields()
    {
        Book book = FetchYourBookFromTheId(selectedBookId);
        var data = GetDatasAboutBookSelected(book);
        ViewBag.Data = data;
        return View();
    }
    return View();
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I have another question about that. In fact, the DropDownList selected value returns the value of the `ToString()` method of `Book` . So I have to put the Ids in my DropDownList, but I would like the list to display the title and the selected value to be the Id. Is there a way to do that? For now, I use this way : the `ToString()` method returns "Id - Title" and I use `SubString()` to keep only the Id. But I would like the DropDownList to display only the Title without the Id. – Azzedine Hassaini Apr 09 '13 at 08:16
  • The `SelectList` class that you are passing to the DropDown is an `IEnumerable` where `SelectListItem` has 2 properties: `Value` and `Text`. You could set the `Value` to the `Id` of your Book instance and the `Text` to whatever format you want. – Darin Dimitrov Apr 09 '13 at 08:24
  • @Darin Dimitrov, It's tremendous! That is what I would like to do! You are the wizard:). – StepUp Sep 19 '14 at 05:17
2

You can use DropDownListFor as below, It so simpler

@Html.DropDownListFor(m => m.Id, new SelectList(Model.Books,"Id","Name","1"))

(You need a strongly typed view for this -- View bag is not suitable for large lists)

   public ActionResult Action(Book model)
   {
        if (ValidateFields()
        {
            var Id = model.Id;
        ...        

I think this is simpler to use.

mesut
  • 2,099
  • 3
  • 23
  • 35