Optional string parameter MVC Routing and ugly urls

I am using mvc 5.2.3 to 4.5.1 and want these urls

  • / Nike / Shoes
  • / Nike / Shoes / Running
  • / Nike / Shirts / 2002342345
  • / Nike / Shoes / Running / 98765432234

My controller has:

[HttpGet]
[Route("{brand}/{category}/{subcategory}/{page:int?}", Name="ProductIndex")]
public ActionResult Index(string brand, string category, int? page, string subcategory = "")

      

and gives / Nike / Shoes / Running but not / Nike / Shoes but / Products? brand = Nike & category = Shoes

When I add

[HttpGet]
[Route("{brand}/{category}/{page:int?}")]
public ActionResult Index(string brand, string category, int? page)

      

/ Nike / Shoes / works, but I also have / Nike / Shoes /? subcategory = Running

and my data method:

[HttpGet]
[Route("{brand}/{category}/{subcategory}/{productid:int:min(9000)}", Name="ProductDetails")]
public ActionResult Details(int productid)

      

gives:

The current request is ambiguous between the following ways: Index System.Web.Mvc.ActionResult (System.String, System.String, System.Nullable`1 [System.Int32], System.String) of type shopmvc.Controllers.ProductsController Index System.Web .Mvc.ActionResult (shopmvc.ViewModels.ProductsViewModel) of type shopmvc.Controllers.ProductsController System.Web.Mvc.ActionResult Details (Int32) of type shopmvc.Controllers.ProductsController

So, something is wrong with my product links and categories / subcategories. or with the way I am trying to achieve it:

<a href="@Url.RouteUrl("ProductDetails", new { brand = item.Brand, category = item.Category, subcategory = item.SubCategory, productid = item.ID })">test</a>
<a href="@Url.Action("Details", "Products", new { brand = item.Brand, category = item.Category, subcategory = item.SubCategory, productid = item.ID })">
<a href="@Url.Action("Index", "Products", new { brand = c.Brand, category = c.Category, subcategory = c.SubCategory })">@c.DisplayName</a>

      

+3


source to share


2 answers


How do I get the top general level and determine the rest from there?

[HttpGet]
[Route("{brand}/{category}/{*subdivision}", Name="ProductIndex")]
public ActionResult Index(string brand, string category, string subdivision)

      



Then determine if your division's division contains a deeper path or productID and calls the correct methods based on that choice

+1


source


Have you tried ordering routes Global.asax

from most specific to most general? Your application doesn't know which order to check for routes, so something like this brand/category/subcategory/nnnnn

could be either on the nnnnn page or on the nnnnn product.

You need to check this route first:

[HttpGet]
[Route("{brand}/{category}/{subcategory}/{productid:int:min(9000)}", Name="ProductDetails")]
public ActionResult Details(int productid)

      

Then this:

[HttpGet]
[Route("{brand}/{category}/{subcategory}/{page:int?}", Name="ProductIndex")]
public ActionResult Index(string brand, string category, int? page, string subcategory = "")

      



Alternatively, you can change the route so that the page route is something like this:

`brand/category/subcategory/p-n`

      

eg. /Nike/Shoes/Running/p-2

EDIT: What happens if you do this? Any number less than 9000 will be interpreted as the number of pages, although this may confuse the user!

[HttpGet]
[Route("{brand}/{category}/{subcategory}/{page:int?:max:8999}", Name="ProductIndex")]
public ActionResult Index(string brand, string category, int? page, string subcategory = "")

      

+2


source







All Articles