title: ASP.NET MVC Core passing a value from dropdownlist in a view to a controller
body: <p>I'm struggling with (perhaps) a simple challenge.
  I have the following classes:</p>
  
  <pre><code>public class Product
  {
  
      public int ID { get; set; }
  
      [Display(Name ="Product Name")]
      public string Name { get; set; }
      public string Description { get; set; }
      public decimal Price { get; set; }
      public int? CategoryID { get; set; }
      public virtual Category Category { get; set; }
  }
  
  public class Category
  {
      public int ID { get; set; }
  
      [Display(Name = "Category Name")]
      public string Name { get; set; }
      public virtual ICollection&lt;Product&gt; Products { get; set; }
  }
  </code></pre>
  
  <p>To store the data I'm using EF Core</p>
  
  <pre><code>public class StoreContext : DbContext
  {
      public StoreContext(DbContextOptions&lt;StoreContext&gt; options) : base(options) { }
  
      public DbSet&lt;Category&gt; Categories { get; set; }
      public DbSet&lt;Product&gt; Products { get; set; }
  }
  </code></pre>
  
  <p>And in my ProductsController I have the following GET method:</p>
  
  <pre><code>public async Task&lt;IActionResult&gt; Index(int category, string search)
  {
      var storeContext = _context.Products.Include(p =&gt; p.Category) as IQueryable&lt;Product&gt;;
  
  
      if (category != 0)
      {
          storeContext = storeContext.Where(p =&gt; p.Category.ID == category);
      }
  
      if (search != null)
      {
          storeContext = storeContext.Where(p =&gt; p.Category.Name == search);
      }
  
      var categories = storeContext.OrderBy(p =&gt; p.Category.Name).Select(p =&gt; p.Category.Name).Distinct();
  
      if (!String.IsNullOrEmpty(search))
      {
          storeContext = storeContext.Where(p =&gt; p.Name.Contains(search)||
          p.Description.Contains(search) ||
          p.Category.Name.Contains(search));
          ViewBag.Search = search;
      }
  
      ViewBag.Category = new SelectList(categories);
  
      return View(await storeContext.ToListAsync());
  }
  </code></pre>
  
  <p>My Index.cshtml looks like as follows:</p>
  
  <pre><code>@model IEnumerable&lt;BabyStore.Models.Product&gt;
  
  @{
      ViewData["Title"] = "Index";
  }
  
  &lt;h2&gt;Index&lt;/h2&gt;
  
  &lt;p&gt;
      &lt;a asp-action="Create"&gt;Create New&lt;/a&gt;
  &lt;/p&gt;
  
  &lt;form asp-action="Index" asp-controller="Products" method="get"&gt;
      &lt;div class="form-group"&gt;
          &lt;table&gt;
              &lt;tr&gt;
                  &lt;td&gt;
                      &lt;label&gt;Filtered by Category: &lt;/label&gt;  
                  &lt;/td&gt;
                  &lt;td&gt;
                      &lt;select class="form-control" asp-items="ViewBag.Category"&gt;
                          &lt;option value=""&gt;-- Select Category --&lt;/option&gt;
                      &lt;/select&gt;
                  &lt;/td&gt;
                  &lt;td&gt;
                      &lt;input type="submit" value="Filter" id="search"/&gt;
                      &lt;input type="hidden" name="search" id="search"/&gt;
                  &lt;/td&gt;
              &lt;/tr&gt;
          &lt;/table&gt;
  
      &lt;/div&gt;
  &lt;/form&gt;
  
  
  &lt;br /&gt;
  
  &lt;table class="table"&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;
                  @Html.DisplayNameFor(model =&gt; model.Description)
              &lt;/th&gt;
              &lt;th&gt;
                  @Html.DisplayNameFor(model =&gt; model.Name)
              &lt;/th&gt;
              &lt;th&gt;
                  @Html.DisplayNameFor(model =&gt; model.Category.Name)
              &lt;/th&gt;
              &lt;th&gt;
                  @Html.DisplayNameFor(model =&gt; model.Price)
              &lt;/th&gt;
              &lt;th&gt;&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
  @foreach (var item in Model) {
          &lt;tr&gt;
              &lt;td&gt;
                  @Html.DisplayFor(modelItem =&gt; item.Description)
              &lt;/td&gt;
              &lt;td&gt;
                  @Html.DisplayFor(modelItem =&gt; item.Name)
              &lt;/td&gt;
              &lt;td&gt;
                  @Html.DisplayFor(modelItem =&gt; item.Category.Name)
              &lt;/td&gt;
              &lt;td&gt;
                  @Html.DisplayFor(modelItem =&gt; item.Price)
              &lt;/td&gt;
              &lt;td&gt;
                  &lt;a asp-action="Edit" asp-route-id="@item.ID"&gt;Edit&lt;/a&gt; |
                  &lt;a asp-action="Details" asp-route-id="@item.ID"&gt;Details&lt;/a&gt; |
                  &lt;a asp-action="Delete" asp-route-id="@item.ID"&gt;Delete&lt;/a&gt;
              &lt;/td&gt;
          &lt;/tr&gt;
  }
      &lt;/tbody&gt;
  &lt;/table&gt;
  </code></pre>
  
  <p>Pushing the "Filter" button should cause refreshing the View and filtering by Category.Name</p>
  
  <p>But, unfortunately it does not work.
  In my browser I read</p>
  
  <pre><code>http://localhost:53827/Products?search=
  </code></pre>
  
  <p>So no parameter has been passed to search.</p>
  
  <p>If I enter by hand</p>
  
  <pre><code>http://localhost:53827/Products?search=clothes 
  </code></pre>
  
  <p>it works perfectly</p>
  
  <p>In the Startup.cs I have the following Route</p>
  
  <pre><code>app.UseMvc(routes =&gt;
          {
              routes.MapRoute(
                  name: "default",
                  template: "{controller=Home}/{action=Index}/{id?}");
          });
  </code></pre>
  
  <p>Any idea how to solve it?</p>