views:

1534

answers:

3

I'm using the MVC beta to write a simple application to understand ASP.Net MVC. The application is a simple photo/video sharing site with tagging. I'm working off the MVC skeleton project. I added some Html.ActionLink()'s to the navigation bar, but I'm having a problem with one of the Html.ActionLink()'s that I added in one spot.

I want ~/Tags to show all tags from the database and I want ~/Tags/{tag} to show a listing of all the files that are tagged with {tag}. This works as expected, but when I follow a ~/Tags/{tag}, it changes the Html.ActionLink() in the navigation bar to be the same as the ~/Tags/{tag} link instead of just pointing to ~/Tags. I'm not understanding why the ActionLink() in my navigation bar is changing when I follow the ~/Tags/{tag}. If I navigate to a different link in the project, the ActionLink() works as expected.

I have the actionlink and route set up like this. My TagsController has this Index action. The int? is for a paging control. I have two Views, one called All and one called Details. What am I doing wrong?

        Html.ActionLink("Tags", "Index", "Tags") // In navigation bar

        routes.MapRoute(
            "Tags",
            "Tags/{tag}",
            new
            {
              controller = "Tags", action = "Index", tag = "",
            });

        public ActionResult Index(string tag, int? id )
        {  // short pseudocode
           If (tag == "")
             return View("All", model)
           else
             return View("Details", model) 
        }
+4  A: 

I think you need to handle an instance of yoursite.com/Tags/, as you're only handling one with a tag in.

I would create another route:

routes.MapRoute(
  "TagsIndex", //Called something different to prevent a conflict with your other route
  "Tags/",
  new { controller = "Tags", action = "Index" }
);

routes.MapRoute(
  "Tags",
  "Tags/{tag}",
  new { controller = "Tags", action = "Tag", tag = "" }
);


/* In your controller */
public ActionResult Index() // You could add in the id, if you're doing paging here
{
  return View("All", model);
}

public ActionResult Tag(string tag, int? id)
{
  if (string.IsNullOrEmpty(tag))
  {
    return RedirectToAction("Index");
  }

  return View("Details", model);
}
Dan Atkinson
Worked like a charm. Your answer gave me an a-ha moment for routing. Thanks!
Ben Robbins
Great! Glad I could help!
Dan Atkinson
A: 

I would suggest you look into Lamda expressions to handle this, you may end up with a 'tag soup' in the future.

Also, make sure you have downloaded the Microsoft.Web.Mvc dll, differs from System.Web.Mvc.

http://stackoverflow.com/questions/334408/where-to-get-microsoftwebmvcdll

+2  A: 

In addition to creating an additional route as Dan Atkinson mentions, you should also get rid of the if statement in the controller and create another controller method (called Details) to handle the tag details. if statements in a controller to determine which view to show are a code smell. Let the routing engine do its job and your controller code will be simpler and easier to maintain.

John Sheehan
the if statement didn't feel right, but fixing the routing got rid of the if.
Ben Robbins