Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly use Html.ActionLink with ASP.NET MVC 4 Areas

I recently discovered Areas in ASP.NET MVC 4, which I have successfully implemented, but I'm running into troubles with the @Html.ActionLink helper in my Razor views. The URL this helper generates always seems to be relative to the URL of the current page.

I have my web site configured in IIS 7 (Win7) as an Application virtual directory at /Foo.

I have two Areas registered: Admin and Blogs. I have the default code in the AdminAreaRegistration.cs and BlogsAreaRegistration.cs files. I added namespaces = new[] { "MvcProject.Controllers" } to the defaults of the default RouteConfig:

public class RouteConfig {     public static void RegisterRoutes(RouteCollection routes)     {         routes.IgnoreRoute("{resource}.axd/{*pathInfo}");          routes.MapRoute(             name: "Default",             url: "{controller}/{action}/{id}",             defaults: new {                 controller = "Home", action = "Index", id = UrlParameter.Optional,                 namespaces = new[] { "MvcProject.Controllers" }             }         );     } } 

When I go to the home page for my site: http://localhost/Foo, it correctly loads the "home" page for my site. At this point, all the action links have their correct URLs.

Sample code from MvcProject/Views/Shared/_Layout.cshtml

<h2>Main Navigation</h2> <ul>     <li>@Html.ActionLink("Home", "Index", "Home")</li>     <li>@Html.ActionLink("Blogs", "Index", "Blogs/Home")</li>     <li>@Html.ActionLink("Admin", "Index", "Admin/Home")</li> </ul> 

This is correctly rendering the HTML as:

<h2>Main Navigation</h2> <ul>     <li><a href="/Foo">Home</a></li>     <li><a href="/Foo/Blogs/Home"></li>     <li><a href="/Foo/Admin/Home"></li> </ul> 

When I navigate in the browser to "Blogs" for instance, this URL correctly loads in the browser: /Foo/Blogs/Home.

Now the links in my main navigation change their URLs to:

<h2>Main Navigation</h2> <ul>     <li><a href="/Foo/Blogs/Home">Home</a></li>     <li><a href="/Foo/Blogs/Blogs/Home"></li>     <li><a href="/Foo/Blogs/Admin/Home"></li> </ul> 

Notice that "Blogs/" is appended to the IIS virtual directory name, so that /Foo/Blogs/Home is now /Foo/Blogs/Blogs/Home.

The controllers and views are rendering fine, it's just the calls to @Html.ActionLink in my MvcProject/Views/Shared/_Layout.cshtml view are not working as I expected.

It feels like I'm missing something trivial, but no amount of searching has come up with an answer. Every blog post and tutorial I've found for implementing Areas in ASP.NET MVC4 makes no mention of changes in how @Html.ActionLink behaves.

like image 350
Greg Burghardt Avatar asked Mar 14 '14 14:03

Greg Burghardt


People also ask

How will you create hyperlink in MVC?

Drag the Employe table from the database in the Server Explorer. The MVC model contains all the application logic validation, Logic Business Logic and data access logic. We can create an employecontext class under the Model Folder. Right-click on Index Actionresult method and select Add view.


1 Answers

I hate answering my own question, but @Matt Bodily put me on the right track.

The @Html.Action method actually invokes a controller and renders the view, so that wouldn't work to create a snippet of HTML in my case, as this was causing a recursive function call resulting in a StackOverflowException. The @Url.Action(action, controller, { area = "abc" }) does indeed return the URL, but I finally discovered an overload of Html.ActionLink that provided a better solution for my case:

@Html.ActionLink("Admin", "Index", "Home", new { area = "Admin" }, null) 

Note: , null is significant in this case, to match the right signature.

Documentation: @Html.ActionLink (LinkExtensions.ActionLink)

Documentation for this particular overload:

LinkExtensions.ActionLink(Controller, Action, Text, RouteArgs, HtmlAttributes)

It's been difficult to find documentation for these helpers. I tend to search for "Html.ActionLink" when I probably should have searched for "LinkExtensions.ActionLink", if that helps anyone in the future.

Still marking Matt's response as the answer.

Edit: Found yet another HTML helper to solve this:

@Html.RouteLink("Admin", new { action = "Index", controller = "Home", area = "Admin" }) 
like image 119
Greg Burghardt Avatar answered Oct 03 '22 11:10

Greg Burghardt