0

Given the following HTML:

 <li>
     <a asp-area="" asp-controller="Product" asp-action="Products" asp-route-id="0">
        <i class="si si-drop"></i>
        <span class="sidebar-mini-hide">EnerBurn</span>
      </a>
  </li>

produces this URL:

https://localhost:44356/Product/Products/0

But in this controller action, the selected variable is always 0. Why isn't the controller action picking up the id from the URL route? This is the HttpGet controller action:

public IActionResult Products(int selected)
{
    var pivm = new ProductInfoViewModel {SelectedId = selected};
    pivm= UpdateModelFromSelectedId(pivm);
    return View(pivm);
}
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
dinotom
  • 4,990
  • 16
  • 71
  • 139

3 Answers3

2

With your current action definition, MVC tries to populate the selected value from query params (this is by default) and fails as you pass it as part of URL.

And so as you want this to be part of URL, you need to specify this explicitly as part of routing:

  • Via route attribute:

    [Route("Product/Products/{selected}")]
    public IActionResult Products(int selected)
    
  • Or if you use the convention routing

    routes.MapRoute("products", {controller=Product}/{action=Products}/{selected?}");
    
Set
  • 47,577
  • 22
  • 132
  • 150
  • @Set...and if I wanted the attribute to be a string value instead of an int, how would I go about that? – dinotom Mar 13 '18 at 13:03
  • @dinotom if you are asking about constraint setup, then check [Route Constraint Reference](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/routing#route-constraint-reference). If you just want to change a parameter type - just modify your method's argument to `string selected` – Set Mar 13 '18 at 13:06
  • This is completely incorrect. Routes ignore query string parameters. Query string values are passed into action methods by [Value Providers](https://stackoverflow.com/a/36606015). If you pass the URL `/product/products?selected=123` it will not match this attribute route at all. – NightOwl888 Mar 13 '18 at 13:22
  • @NightOwl888 just reread question - he wants to have a URL like `/product/products/selected` – Set Mar 13 '18 at 14:00
  • Ok, I still stand by the fact that query params are not picked up by routes at all unless you customize routing to consider them. You should remove that part from your answer. – NightOwl888 Mar 13 '18 at 14:17
0

Change the code and put id instead of selected:

public IActionResult Products(int id)
{
    var pivm = new ProductInfoViewModel {SelectedId = id};
    pivm= UpdateModelFromSelectedId(pivm);
    return View(pivm);
}
Kirk Larkin
  • 84,915
  • 16
  • 214
  • 203
Eri-Ka
  • 49
  • 1
  • 8
0

Why use "int selected"? It requires custom routing.

Use "string id" and MVC will handle it for you by default. If you need the input parameter to be an int, then convert it to an int (in try catch?).

//in: id represents selected index
public IActionResult Products(string id)
{
int selected = Convert.ToUInt32(id);
//do work....
}
1c1cle
  • 433
  • 3
  • 6