Ben Robbins
Ben Robbins

Reputation: 2630

ASP.Net MVC Html.ActionLink() problems

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) 
        }

Upvotes: 2

Views: 3651

Answers (3)

Dan Atkinson
Dan Atkinson

Reputation: 11689

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);
}

Upvotes: 4

John Sheehan
John Sheehan

Reputation: 78104

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.

Upvotes: 2

acidhorse
acidhorse

Reputation:

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.

Where to get Microsoft.Web.Mvc.dll

Upvotes: 0

Related Questions