1
votes

I have simple question about MVC routing. How i can construct Html.ActionLink thhat generates following link http://mysite.com/phones/samsung
Now it's generates as http://mysite.com/phones/brand?brand=samsung
Also i want to avoid mentioning action name in URL
There is my code:

Route:

routes.MapRoute(null, "Phones/{brand}", 
new { controller = "Phones", action = "Index", brand = UrlParameter.Optional });

Controller:

MySyteDBEntities ms = new MySyteDBEntities();

public ActionResult Index()
{
    ViewBag.Brand = ms.Phones.Select(x => x.Brand).Distinct();
    return View();            
}

public ActionResult Brand(string brand)
{
    ViewBag.Standard = ms.Phones.Where(x => x.Brand == brand).Select(x => x.Standard).Distinct();
        return View();
}

Index View code:

@foreach (string item in ViewBag.Brand)
{                    
    <div>@Html.ActionLink(item, "Brand", new { brand = item })</div>
}
5
The second token is called brand in the MapRoute. In the actionlink it was called category. If you call it the same in both places it should work. - Naraen

5 Answers

3
votes

In your MapRoute you have no space for an action, so asp.net will always use the default action "Index".

By default your routing would look like this:

routes.MapRoute(" Default", "{controller}"/{action}/{id}", 
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }

You're missing the action part.

Routevalues in you actionlink which don't match parameters in your route, will be querystring parameters. So you need to change "category" to " brand" in your route.

Try this:

routes.MapRoute(null, "Phones/{brand}", 
 new { controller = "Phones", action = "Index", brand = UrlParameter.Optional });

and

@foreach (string item in ViewBag.Brand)
{                    
 <div>@Html.ActionLink(item, "Index", "Phones", new { brand = item }, null)</div>
}

Be sure to call the controller explicit in your ActionLink, if the current view is mapped through another route, otherwise it doesn't recognize the brand parameter.

1
votes

Try (this route should be registered before the default route, if you have one)

        routes.MapRoute(
         "Phones", // Route name
         "Phones/{[^(Index)]brand}", // URL with parameters
         new { controller = "Phones", action = "Brand", brand = "" } // Parameter defaults
     );

With this, http://mysite.com/phones/ --> should go to Index Action and http://mysite.com/phones/samsung --> should go to the Brand Action.

1
votes

i'm found source of problem. I just need to remove last piece (brand optional parameter) in MapRoute. Hare is code:

routes.MapRoute(null, "Phones/{brand}", new { controller = "Phones", action = "Brand" });
0
votes
routes.MapRoute(null, "Phones/{id}", 
new { controller = "Phones", action = "Index", id= UrlParameter.Optional })

public ActionResult Brand(string id)
{
    ViewBag.Standard = ms.Phones.Where(x => x.Brand == brand).Select(x => x.Standard).Distinct();
        return View();
}

By using id as the parameter name, it will prevent the routing from using the querystring key value pairs.

Your parameterless GET and View code should still work without any changes.

0
votes

If I remember correctly, the {brand} part needs to be included as is as part of your parameters:

routes.MapRoute(null, "Phones/{brand}", 
new { controller = "Phones", action = "Index", brand = UrlParameter.Optional });

Just remember, it needs to go before any default routes.