How to get input text from selected dropdown in ASP.NET Core 3.1 MVC

Viewed 7539

I am using ASP.NET Core 3.1 MVC to create a page with a form. The dropdown is populated with data from the database. In my controller, I want to capture the text of the selected item from the dropdown. Right now I am able to capture the ID associated with the selected item.

My Model:

public int ID { get; set; }
public string bookName { get; set; }
public string Author { get; set; }

My cshtml:

<form method="post" asp-controller="Index" asp-action="Index" role="post">
    <div class="form-group">
        <label asp-for="bookName"></label>
        <select name="bookName" asp-items="@(new SelectList(ViewBag.message, "ID", "bookName"))"></select>
    </div>
</form>

My Controller:

        public void PopulateBooks()
        {
            List<bookModel> bookName = new List<bookModel>();
            bookName = (from a in _context.bookModel select a).ToList();
            bookName.Insert(0, new bookModel { ID = 0, bookName = "" });
            ViewBag.message = bookName;
        }

[HttpPost]
public async Task<IActionResult> Index([FromForm] bookModel model)
{
  string bookName = HttpContext.Request.Form["bookName"];
}

My string variable "bookName" returns the ID with the selected book, but I want the name of the selected book. Thanks!

1 Answers

This is not specific to Asp.Net MVC or Razor, but it's a general browser side design practice for posting form data to your server side application. <option> elements in a <select> element have value as an attribute and an inner text for its display text.

<select name="mySelect">
  <option value="1">bookname 1</option>
  <option value="2">bookname 2</option>
  <option value="3">bookname 3</option>
</select>

When you post the form to your web application, browser serializes the value attribute of selected option and then posts it along with other input values in your form.

Best approach here is sticking to passing the book ID information instead of book Name, and then retrieving the matching book record with that ID from database on server side again. This approach will prevent users sending unwanted texts to your application. Otherwise, they can post whatever they want other than what is inside your select box by using JavaScript.

Change your select element name to "ID" and you can retrive ID value in your model when you post the form. And use that ID to find book name from your database.

<form method="post" asp-controller="Index" asp-action="Index" role="post">
    <div class="form-group">
        <label asp-for="ID"></label>
        <select name="ID" asp-items="@(new SelectList(ViewBag.message, "ID", "bookName"))"></select>
    </div>
</form>

[HttpPost]
public async Task<IActionResult> Index([FromForm] bookModel model)
{
  int bookID = model.ID;
  model.bookName = (from a in _context.bookModel where a.ID == bookID select a.bookName).FirstOrDefault()
  // do whatever you want to do with book name using model.bookName now...
}

But if you still actually want to post the book name despite this best practice, then you can simply use book name for both value and text information.

<select name="bookName" asp-items="@(new SelectList(ViewBag.message, "bookName", "bookName"))"></select>

This will produce :

<select name="bookName">
  <option value="bookname 1">bookname 1</option>
  <option value="bookname 2">bookname 2</option>
  <option value="bookname 3">bookname 3</option>
</select>
Related