0

I have the following controller:

    public ActionResult Index(int? categoryId)
    {
        IList<Item> result = categoryId == null ? _itemsService.GetLast(20) : _itemsService.GetByCategory((int)categoryId);
        var viewModel = Mapper.Map<IList<Item>, IList<ItemsIndexViewModel>>(result);
        return View(viewModel);
    }

The nullable categoryId parameter refers to the id of a sub-category. In case nothing was passed, the last 20 items must be displayed, but if a sub-category id was passed, the items from that category should be displayed.

But what I'm trying to go for is: www.myDomain.com/Category/SubCategory (ex: /Electronics/Cell-Phones)

My attempt at writing a route is this:

        routes.MapRoute(
            "ItemIndex",
            "{category}/{subcategory}",
            new {controller = "Item", action = "Index", categoryId = UrlParameter.Optional}
            );

But I have no idea how to pass the values of the category and subcategory.

Any help would be appreciated :)

UPDATE: Here are the route definitions I've got so far:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.([iI][cC][oO]|[gG][iI][fF])(/.*)?" });

        routes.MapRoute(
                "ItemDetail",
                "Item/Detail/{itemId}",
                new { controller = "Item", action = "Detail" }
            );

        routes.MapRoute(
            "ItemIndex",
            "Items/{category}/{subcategory}",
            new { controller = "Item", action = "Index", subcategory = UrlParameter.Optional }
            );

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

    }

This is my controller I wish to map the route to:

    public ActionResult Index(string category, string subcategory)
    {
       // IList<Item> result = string.IsNullOrEmpty(subcategory) ? _itemsService.GetLast(20) : _itemsService.GetByCategory(subcategory);
        IList<Item> result;
        if (string.IsNullOrEmpty(subcategory))
        {
            if (string.IsNullOrEmpty(category))
            {
                result = _itemsService.GetLast(20);
            }
            else
            {
                result = _categoryService.GetItemsInTopLevel(category);
            }
        } else
        {
            result = _itemsService.GetByCategory(subcategory);
        }
        var viewModel = Mapper.Map<IList<Item>, IList<ItemsIndexViewModel>>(result);
        return View(viewModel);
    }

And here's how I'm calling it from the View:

@model IList<Sharwe.MVC.Models.ParentCategory>

<div id="sharwe-categories">
    <ul class="menu menu-vertical menu-accordion">
        @foreach(var topLevel in Model)
        {
             <li class="topLevel">
                <h3>  
                    @Html.ActionLink(topLevel.Name, "Index", "Item", new { category = topLevel.Name }, new {@class = "main"} )
                    <a href="#" class="drop-down"></a>
                </h3>
                <ul>
                    @foreach (var childCategory in topLevel.Children)
                    {
                        <li>@Html.ActionLink(childCategory.Name, "Index", "Item", new RouteValueDictionary{ { "category" , topLevel.Name }, { "subcategory" , childCategory.Name }})</li>
                    }
                </ul>
            </li>
        }

    </ul>

</div>

When I click on a top level category, it works perfectly fine. But clicking on the sub-categories does not work. It actually redirects to http://localhost/?Length=4. I have no idea where this is coming from.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Kassem
  • 8,116
  • 17
  • 75
  • 116
  • don't you think your route will match Home/create url as well or i m missing something? – Muhammad Adeel Zahid Apr 15 '11 at 18:14
  • @Muhammad Adeel Zahid: Actually I think it does. Right now, I was debugging and I noticed the Home/Index got triggered right away... Why is that happening and how can I prevent it? – Kassem Apr 15 '11 at 19:15
  • You will probably have to use some route constraints as well. It's usually easier to make route definition similar to `category/{category}/{subcategory}` so it will be much easier to constraint it. – Robert Koritnik Apr 15 '11 at 19:42

1 Answers1

2

Pass them in controller action method as parameters

public ActionResult Index(string category, string subcategory)
{
    if (string.IsNullOrEmpty(subcategory))
    {
        // display top 20
    }
    else
    {
        // display subcategory
    }
}

Strings are already reference types so you don't have to set anything else.

Robert Koritnik
  • 103,639
  • 52
  • 277
  • 404
  • @Robert Koritnik: makes sense! That means rather than passing the Id using the Html.ActionLink I should pass those parameters instead. Mind updating your answer to show how the parameters will be passed from the view please? – Kassem Apr 15 '11 at 17:34
  • @Robert Koritnik: Is this the correct format: `@Html.ActionLink(childCategory.Name, "Index", "Item", { category = topLevel.Name, subcategory = childCategory.Name })` – Kassem Apr 15 '11 at 17:40
  • @Kassem: Of course. That's correct notation. You always have to provide those parameters that are required by route otherwise route won't be able to generate link URL and next one in line will try to generate it. – Robert Koritnik Apr 15 '11 at 19:39
  • @Robert Koritnik: It still doesn't work for me! I will update my post and show you what I got so far. – Kassem Apr 15 '11 at 19:46
  • 1
    @Kassem: Have you tried this: `
  • @Html.ActionLink(childCategory.Name, "Index", "Item", new { category = topLevel.Name , subcategory = childCategory.Name }, null)
  • ` – Robert Koritnik Apr 15 '11 at 20:42
  • @Robert Koritnik: That actually worked! Thank you! But I do not understand why that happens... – Kassem Apr 15 '11 at 20:45
  • @Robert Koritnik: By the way, now it causes another issue... :( Here it is: http://stackoverflow.com/questions/5682160/asp-net-mvc-a-potentially-dangerous-request-path-value-was-detected-from-the-cl – Kassem Apr 15 '11 at 20:46