ASP.NET MVC`Html.ActionLink`在“区域”之间

时间:2011-03-25 12:04:46

标签: asp.net-mvc razor asp.net-mvc-areas

我已经为我的MVC3项目添加了一个新区域,我正在尝试从_Layout页面链接到新区域。我添加了一个名为“Admin”的区域,它有一个控制器“Meets”。

我使用visual studio designer来添加区域,使其具有正确的区域注册类等,并且global.asax文件正在注册所有区域。

但是,当我在根页面中使用以下2个操作链接时,我遇到了一些问题:

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

当点击这两个链接时,我被带到管理区域中的Meets控制器,然后应用程序继续抛出错误,说它无法找到索引页面(即使索引页面存在于视图文件夹中区域子目录。

第一个链接的href如下所示:

http://localhost/BCC/Meets?area=Admin

第二个链接的href看起来像这样:

http://localhost/BCC/Meets

此外,如果我点击了我希望创建的链接:

http://localhost/BCC/Admin/Meets

我只是得到一个无法找到资源的错误。一切都非常令人困惑!我希望有人能帮忙......

6 个答案:

答案 0 :(得分:72)

确实很奇怪。对我来说非常好的步骤:

  1. 使用默认的Visual Studio模板
  2. 创建一个新的ASP.NET MVC 3应用程序
  3. 通过右键单击项目
  4. ,使用Visual Studio设计器添加名为Admin的区域
  5. ~/Areas/Admin/Controllers/MeetsController中添加新的控制器:

    public class MeetsController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
    
  6. 添加相应的视图~/Areas/Admin/Views/Meets/Index.cshtml

  7. 在布局(~/Views/Shared/_Layout.cshtml)中添加链接:

    @Html.ActionLink("Admin", "Index", "Meets", new { area = "Admin" }, null)
    @Html.ActionLink("Admin", "Index", "Meets", new { area = "" }, null)
    
  8. 运行该应用程序。
  9. 为锚点呈现HTML:

    <a href="/Admin/Meets">Admin</a>
    <a href="/Meets">Admin</a>
    

    正如预期的那样,第一个链接起作用,而第二个链接不起作用。

    那么你的设置有什么不同?

答案 1 :(得分:30)

另一个选择是使用RouteLink()而不是ActionLink(),它完全绕过区域注册:

ActionLink版本:

Html.ActionLink("Log Off", "LogOff", "Account", new { area = "" }, null)

RouteLink版本:

Html.RouteLink("Log Off", "Default", 
    new { action = "LogOff", controller = "Account" })

第二个参数是“路径名称”,它在Global.asax.cs和各种“AreaRegistration”子类中注册。要使用“RouteLink”链接不同区域,您只需指定正确的路径名称。

以下示例显示了如何从共享部分生成到不同区域的三个链接,无论我在哪个区域(如果有),它都能正常工作:

@Html.RouteLink("Blog", "Blog_default", 
    new { action = "Index", controller = "Article" })
<br/>
@Html.RouteLink("Downloads", "Download_default", 
    new { action = "Index", controller = "Download" })
<br/>
@Html.RouteLink("About", "Default", 
    new { action = "Index", controller = "About" })

快乐的编码!

答案 2 :(得分:7)

我想出了这一点 - 我创建了一个新的测试项目并完成了我以前做过的完全相同的事情并且它有效...然后在进一步检查两个项目之间的所有相关路线后,我发现了一个差异。< / p>

在我的BCC应用程序中的global.asax文件中,出现了一个无法解释的流氓代码:

        public static void RegisterRoutes(RouteCollection routes)
        {
            // Problem here
            routes.Clear();

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );
        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }

正如你可以看到我的评论在哪里,在某个时间或其他地方我已经在RegisterRoutes的开头放置了routes.Clear()调用,这意味着在我在Application_Start中注册了区域后,我立即清除了什么我刚刚注册了。

感谢您的帮助......它最终导致了我的救赎!

答案 3 :(得分:3)

验证您的AdminAreaRegistration课程如下:

public class AdminAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "Admin";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "Admin_default",
            "Admin/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }
        );
    }
}

并且你在Global.asax.cs

中有这个
protected void Application_Start()
{
    ... // ViewEngine Registration
    AreaRegistration.RegisterAllAreas();
    ... // Other route registration
}

答案 4 :(得分:2)

我通过执行以下操作解决了这个问题。

在我的Global.asax.cs中,我有

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
    }

    protected void Application_Start()
    {
        //Initialise IoC
        IoC.Initialise();

        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }

在我的PublicAreaRegistration.cs(公共区域)中,我有

public class PublicAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "Public";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute("Root", "", new { controller = "Home", action = "Index" });

        context.MapRoute(
            "Public_default",
            "Public/{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            , new[] { "<Project Namespace here>.Areas.Public.Controllers" }
        );
    }
}

在我的AuthAreaRegistration.cs(限制访问区域)中,我有

public class AuthAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "Auth";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "Auth_default",
            "Auth/{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

最后,我的* .cshtml页面中的链接就像

1)@ Html.ActionLink(“注销”,“LogOff”,新{area =“Public”,controller =“Home”})

2)@ Html.ActionLink(“管理区域”,“索引”,新{area =“Auth”,控制器=“主页”})

希望这可以节省一些时间的研究!顺便说一下,我在这里谈论MVC3。

Kwex。

答案 5 :(得分:1)

大多数开发人员可能不是这种情况,但是当我添加第一个区域并且没有构建我的解决方案时,我遇到了这个问题。一旦我构建了我的解决方案,链接就会开始正确填充。