如何正确使用Html.ActionLink与ASP.NET MVC 4区域

时间:2014-03-14 14:19:31

标签: c# asp.net-mvc-4 razor asp.net-mvc-routing

我最近发现Areas in ASP.NET MVC 4,我已成功实施,但我在Razor视图中遇到了@Html.ActionLink帮助器的问题。此助手生成的URL似乎总是相对于当前页面的URL。

我将我的网站在IIS 7(Win7)中配置为/Foo的应用程序虚拟目录。

我注册了两个区域:管理员和博客。我在AdminAreaRegistration.csBlogsAreaRegistration.cs文件中有默认代码。我将namespaces = new[] { "MvcProject.Controllers" }添加到默认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" }
            }
        );
    }
}

当我转到我的网站的主页:http://localhost/Foo时,它会正确加载" home"我的网站的页面。此时,所有操作链接都有正确的URL。

来自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>

这正确地将HTML呈现为:

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

当我在浏览器中导航到&#34; Blogs&#34;例如,此网址在浏览器中正确加载:/Foo/Blogs/Home

现在,我主导航中的链接会将其网址更改为:

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

请注意&#34; Blogs /&#34;附加到IIS虚拟目录名称,以便/Foo/Blogs/Home现在是/Foo/Blogs/Blogs/Home

控制器和视图呈现正常,只是我@Html.ActionLink视图中对MvcProject/Views/Shared/_Layout.cshtml的调用无法正常工作。

感觉我错过了一些微不足道的事情,但没有多少搜索得出答案。我在ASP.NET MVC4中实现区域的每个博客文章和教程都没有提及@Html.ActionLink行为的变化。

4 个答案:

答案 0 :(得分:71)

我讨厌回答我自己的问题,但@Matt Bodily让我走上正轨。

@Html.Action方法实际调用控制器并呈现视图,因此在我的情况下不会创建HTML片段,因为这会导致递归函数调用导致StackOverflowException。 @Url.Action(action, controller, { area = "abc" })确实返回了URL,但我终于发现了Html.ActionLink的重载,为我的案例提供了更好的解决方案:

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

注意: , null在这种情况下很重要,以匹配正确的签名。

文档:@Html.ActionLink (LinkExtensions.ActionLink)

此特定过载的文档:

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

很难找到这些助手的文档。我倾向于搜索&#34; Html.ActionLink&#34;当我可能应该搜索&#34; LinkExtensions.ActionLink&#34;时,如果这有助于将来的任何人。

仍然将马特的回答作为答案。

编辑:找到另一个HTML助手来解决这个问题:

@Html.RouteLink("Admin", new { action = "Index", controller = "Home", area = "Admin" })

答案 1 :(得分:16)

如何重定向到某个区域,将其添加为参数

@Html.Action("Action", "Controller", new { area = "AreaName" })

对于我使用的链接的href部分

@Url.Action("Action", "Controller", new { area = "AreaName" })

答案 2 :(得分:2)

只是加上我的位:
请记住,您需要在MVC应用程序中至少有2个区域才能使routeValues: { area="" }正常工作;否则,区域值将用作查询字符串参数,您的链接将如下所示:/?area=

如果您没有至少2个区域,则可以通过以下方式解决此问题:
1.在RouteConfig.cs中编辑默认路线,如下所示:

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { area = "", controller = "Home", action = "Index", id = UrlParameter.Optional }
);

OR
2.在MVC项目中添加虚拟区域。

答案 3 :(得分:0)

下面是在MVC中创建链接按钮的一些方法。

@Html.ActionLink("Admin", "Index", "Home", new { area = "Admin" }, null)  
@Html.RouteLink("Admin", new { action = "Index", controller = "Home", area = "Admin" })  
@Html.Action("Action", "Controller", new { area = "AreaName" })  
@Url.Action("Action", "Controller", new { area = "AreaName" })  
<a class="ui-btn" data-val="abc" href="/Home/Edit/ANTON">Edit</a>  
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#CustomerList" href="/Home/Germany">Customer from Germany</a>  
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#CustomerList" href="/Home/Mexico">Customer from Mexico</a> 

希望这会对您有所帮助。