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

发布于 2024-10-27 05:18:48 字数 757 浏览 5 评论 0原文

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

我使用 Visual Studio 设计器添加区域,以便它具有正确的区域注册类等,并且 global.asax 文件正在注册所有区域。

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

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

单击这两个链接时,我将被带到管理区域中的 Meets 控制器,然后应用程序将在其中引发错误说它找不到索引页面(即使索引页面存在于 Area 子目录的 Views 文件夹中。

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

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

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

http://localhost/BCC/Meets

另外,如果我点击我期望创建的链接:

http ://localhost/BCC/Admin/Meets

我刚刚收到一个资源无法找到的错误,我希望有人可以帮助...

I have added a new Area to my MVC3 project and I am trying to link from the _Layout page to the new Area. I have added an Area called 'Admin' that has a controller 'Meets'.

I used the visual studio designer to add the area so it has the correct area registration class etc, and the global.asax file is registering all areas.

However, when I use the following 2 action links in a page in the root, I run into a few problems:

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

When clicking both links, I am taken to the Meets controller in the Admin area, where the application then proceeds to throw an error saying it cannot find the Index page (even though the Index page is present in the Views folder in the Area sub-directory.

The href for the 1st link looks like this:

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

And the href for the 2nd link looks like this:

http://localhost/BCC/Meets

Also if I hit the link that I expect to be created:

http://localhost/BCC/Admin/Meets

I just get a resource cannot be found error. All very perplexing! I hope someone can help...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

缺⑴份安定 2024-11-03 05:18:49

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

在我的 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("Log Off", "LogOff", new{area= "Public",controller="Home"})

2) @Html.ActionLink("Admin Area", "Index ", new {area= "Auth",controller="Home"})

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

奎克斯。

I solved this problem by doing the following.

In my Global.asax.cs, I have

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

In my PublicAreaRegistration.cs (Public Area), I've got

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

In my AuthAreaRegistration.cs (Area for Restricted access), I've got

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

And finally, my links in my *.cshtml pages would be like

1) @Html.ActionLink("Log Off", "LogOff", new{area= "Public", controller="Home"})

or

2) @Html.ActionLink("Admin Area", "Index", new {area= "Auth", controller="Home"})

Hope this saves someone hours of research! BTW, I'm talking about MVC3 here.

Kwex.

划一舟意中人 2024-11-03 05:18:49

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

This might not be the case for most of the developers but I encountered this problem when I added a my first area and did not build my solution. As soon as I build my solution the links started to populate correctly.

蒲公英的约定 2024-11-03 05:18:48

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

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

    公共类 MeetsController :控制器
    {
        公共 ActionResult Index()
        {
            返回视图();
        }
    }
    
  4. 添加相应的视图~/Areas/Admin/Views/Meets/Index .cshtml

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

    @Html.ActionLink("Admin", "Index", "Meets", new { area = "Admin" }, null)
    @Html.ActionLink("Admin", "Index", "Meets", new { area = "" }, null)
    
  6. 运行应用程序。

锚点的渲染 HTML:

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

正如预期的那样,第一个链接有效,而第二个链接无效。

那么和你的设置有什么区别呢?

Strange indeed. Steps that worked perfectly fine for me:

  1. Create a new ASP.NET MVC 3 application using the default Visual Studio template
  2. Add an area called Admin using Visual Studio designer by right clicking on the project
  3. Add new Controller in ~/Areas/Admin/Controllers/MeetsController:

    public class MeetsController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
    
  4. Add a corresponding view ~/Areas/Admin/Views/Meets/Index.cshtml

  5. In the layout (~/Views/Shared/_Layout.cshtml) add links:

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

Rendered HTML for the anchors:

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

As expected the first link works whereas the second doesn't.

So what's the difference with your setup?

耶耶耶 2024-11-03 05:18:48

另一种选择是使用 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" })

快乐编码!

Another option is to utilize RouteLink() instead of ActionLink(), which bypasses the area registrations altogether:

ActionLink version:

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

RouteLink version:

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

The second parameter is a "Route Name" which is registered in Global.asax.cs and in various 'AreaRegistration' subclasses. To use 'RouteLink' to link between different areas, you only need to specify the correct route name.

This following example shows how I would generate three links to different areas from a shared partial, which works correctly regardless of which area I am 'in' (if any):

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

Happy coding!

梦里人 2024-11-03 05:18:48

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

在我的 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);
        }

正如您所看到的,我的注释在哪里,有时我在开头放置了 paths.Clear() 调用RegisterRoutes,这意味着当我在Application_Start中注册了Areas之后,我立即清除了我刚刚注册的内容。

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

I figured this out - I created a new test project and did exactly the same thing I was doing before and it worked...then after further inspection of all things route-related between the two projects I found a discrepancy.

In the global.asax file in my BCC application, there was a rogue line of code which had inexplicably appeared:

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

As you can see where my comment is, at some time or other I had placed the routes.Clear() call at the beginning of RegisterRoutes, which meant after I had registered the Areas in Application_Start, I was then immediately clearing what I had just registered.

Thanks for the help...it did ultimately lead to my salvation!

柠栀 2024-11-03 05:18:48

验证您的 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
}

Verify that your AdminAreaRegistration class looks like this:

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

and that you have this in Global.asax.cs:

protected void Application_Start()
{
    ... // ViewEngine Registration
    AreaRegistration.RegisterAllAreas();
    ... // Other route registration
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文