【问题标题】:ASP.NET MVC3 Area controller accessible from global routes?可从全局路由访问的 ASP.NET MVC3 区域控制器?
【发布时间】:2011-10-15 23:17:23
【问题描述】:

也许我没有正确理解 MVC 区域是如何工作的,但这让我有点困惑。

  1. 在 MVC3 项目的 Visual Studio 中右键单击“添加区域”,添加一个名为“MyArea”的区域
  2. 为 MyArea 创建一个控制器:“AnArea”,在 MyArea 区域中具有匹配的视图。
  3. 在 MyAreaAreaRegistration.RegisterArea 方法中将“controller = “AnArea”添加到 context.MapRoute 的默认参数。

因此,此时如果您启动应用程序并导航到 /MyArea/,它应该会加载带有匹配视图的 AnArea 控制器。如果您导航到 /MyArea/AnArea,它将显示相同的结果。

但是,如果您导航到 /AnArea/,仍会找到控制器并显示以下错误消息:

The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/anarea/Index.aspx
~/Views/anarea/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/anarea/Index.cshtml
~/Views/anarea/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml

这是正确的行为吗?我原以为一个区域的控制器只能通过它自己的区域而不是全局访问。

【问题讨论】:

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


【解决方案1】:

每当我创建一个带有区域的项目时,我都会将我的Default 路由更改如下:

    routes.MapRoute( 
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // defaults
        null,  // constraints
        new string[] { "MyApplication.Controllers" } // namespaces
    );

最后一个参数将默认路由限制到MyApplication.Controllers 命名空间中的控制器。这可确保默认路由仅限于任何区域之外的操作。

更新

深入研究代码后,我发现了问题所在,并找到了解决方案。将您的默认路由更改为以下内容:

routes.Add(
    "Default", 
    new Route("{controller}/{action}/{id}",
        new RouteValueDictionary(
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        ),
        null,
        new RouteValueDictionary(
            new {
                Namespaces = new string[] { "MyApplication.Controllers" },
                UseNamespaceFallback = false 
            }
        ),
        new MvcRouteHandler()
    )
);

关键在于添加UseNamespaceFallback 令牌。这将阻止默认路由查看任何其他名称空间。

这是出乎意料的行为,我不知道这是一个影响我正在从事的项目的问题。我将在 aspnet.codeplex.com 上将其列为问题。我不会将此称为错误,但这种行为显然违反了 MVC 路由的约定。

【讨论】:

  • 这似乎不起作用,区域控制器仍在通过/anarea/激活我的控制器位于命名空间:TestAreaControllerAccessibleFromGlobal.Areas.MyArea.Controllers,我添加了命名空间'TestAreaControllerAccessibleFromGlobal.Controllers ' 到默认路由注册(这是创建新项目时放置 HomeController 的地方)
  • 您是否在 Global.asax.cs 中定义了任何其他路由?
  • 不,只有“默认”路线以及您在回答中建议的修改: routes.MapRoute( "Default", // 路线名称 "{controller}/{action}/{id}" , // 带参数的 URL new { controller = "Home", action = "Index", id = UrlParameter.Optional}, // 参数默认为 null, // 约束 new[] { "TestAreaControllerAccessibleFromGlobal.Controllers" } // 命名空间) ;
  • 更新后的解决方案有效,感谢您研究它。我确实认为这是一个有点奇怪的行为......
【解决方案2】:

您必须在区域和一般路线中应用命名空间限制。

在 global.asax.cs 中你应该像这样编辑 RegisterRoutes 方法

public static void RegisterRoutes(RouteCollection routes)
{
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   routes.MapRoute(
      "Default", 
      "{controller}/{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional }, 
      new string[] { "MyProject.Controllers" }
   );
}

这会将“//”限制在命名空间“MyProject.Controllers”中

但您还必须将命名空间限制应用于区域以将“//”仅限制在命名空间“MyProject.Areas.MyArea.Controllers”

为此,您必须编辑“MyAreaAreaRegistration.cs”的“RegisterArea”方法,如下所示(“MyAreaRegistration.cs”位于“/MyProject/Areas/MyArea”文件夹):

//Some default code stuff
...
public override void RegisterArea(AreaRegistrationContext context)
{
   context.MapRoute(
      "MyArea_default",
      "MyArea/{controller}/{action}/{id}",
      new { action = "Index", id = UrlParameter.Optional },
      new string[] { "MyProject.Areas.MyArea.Controllers" }
   );
}

希望对你有帮助!!

【讨论】:

  • 肯定有一些东西丢失了,我创建了一个新的 MVC3 项目,添加了一个名为 MyArea 的新区域,进行了您建议的上述更改,但区域的控制器仍然从全局可见...即 // AreaHome 调用命名空间“MyProject.Areas.MyArea.Controllers”中的 /MyArea/Controllers/AreaHomeController。
【解决方案3】:

您似乎正在导航到/AnArea,而您的区域称为MyArea,因此您应该导航到/MyArea/。区域路由注册如下所示:

context.MapRoute(
    "MyArea_default",
    "MyArea/{controller}/{action}/{id}",
    new { controller = "AnArea", action = "Index", id = UrlParameter.Optional }
);

AnArea 是控制器的名称,而不是区域的名称。如果您想导航到该区域的某个控制器,您应该始终在您的 url 前面加上 MyArea 这是该区域的名称。

【讨论】:

  • 我理解这一点,我很好奇的行为是如何阻止 /AnArea/ 解析为 MyArea 的 AnArea 控制器。看来辅导员本已经找到了解决办法,所以还是谢谢
猜你喜欢
  • 2012-06-13
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 2014-03-02
  • 2011-07-29
相关资源
最近更新 更多