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

本文关键字:NET ASP MVC 领域 ActionLink 何正确 Html | 更新日期: 2023-09-27 17:50:13

我最近发现在ASP领域。. NET MVC 4,我已经成功实现了,但是我在Razor视图中的@Html.ActionLink helper中遇到了麻烦。这个帮助器生成的URL似乎总是相对于当前页面的URL。

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

我注册了两个区域:Admin和Blogs。我在AdminAreaRegistration.csBlogsAreaRegistration.cs文件中有默认代码。我将namespaces = new[] { "MvcProject.Controllers" }添加到默认routecconfig的默认值中:

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时,它正确地加载了我的网站的"主页"。至此,所有的操作链接都有了正确的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>

例如,当我在浏览器中导航到"Blogs"时,浏览器会正确加载以下URL: /Foo/Blogs/Home .

现在,我的主导航中的链接将它们的url更改为:
<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>

请注意,"Blogs/"被附加到IIS虚拟目录名称后,因此/Foo/Blogs/Home现在是/Foo/Blogs/Blogs/Home

控制器和视图渲染很好,它只是调用@Html.ActionLink在我的MvcProject/Views/Shared/_Layout.cshtml视图不像我预期的那样工作。

感觉我错过了一些微不足道的东西,但再多的搜索也没有找到答案。我找到的在ASP中实现area的每一篇博客文章和教程。NET MVC4没有提到@Html.ActionLink行为的变化

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

我讨厌回答自己的问题,但是@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)

很难找到这些帮助程序的文档。我倾向于搜索"Html"。ActionLink",而我可能应该搜索"LinkExtensions"。ActionLink",如果这对将来有帮助的话。

仍然把Matt的回答作为答案。

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

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

如何重定向到一个区域是添加它作为一个参数

@Html.Action("Action", "Controller", new { area = "AreaName" })
对于链接的href部分,我使用
@Url.Action("Action", "Controller", new { area = "AreaName" })

把我的比特加起来:
记住,你需要在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 }
);


2. 在MVC项目中添加一个虚拟区域

下面是一些在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>