MVC5中如何防止controller在错误区域被使用
How to prevent controllers in wrong areas from being used in MVC5
我的 MVC 应用程序设置了 root/global 级别的控制器。这些没有明确的区域。我还有一个 "Admin" 区域。 URL以 /admin/ 开头的将被路由到管理区域中的匹配控制器。其他 URL 被路由到匹配的全局控制器。这在大多数情况下工作正常。
我遇到的问题是,如果 URL 与管理区域中的控制器匹配,而全局区域中不存在同名控制器,则请求路由错误到管理区域的控制器。我知道会发生这种情况,因为我在相关控制器中的匹配操作上设置了断点。
例如,我在管理区有一个名为CalendarController
的控制器。当我访问 /admin/calendar
时,它起作用了,因为它在 Areas/Admin/Views/Calendar/Index.cshtml
中找到了操作和相应的视图。当我访问 /calendar
时出现问题。我在根级别没有名为 Calendar 的控制器,但出于某种原因它将请求路由到我不想要的管理区域的 CalendarController
。我希望它成为 return 404,因为根级别不存在 CalendarController
。相反,我收到一个错误,因为它正在根级别(/Views/Calendar/Index.cshtml
)搜索视图,即使匹配的控制器位于管理区域。
如何防止在管理区域中搜索匹配的控制器,除非 URL 中有 /admin?
这是相关的路由代码,除了名称空间添加之外,它基本上是库存的。如果没有命名空间,问题仍然存在。实际应用中有更多的路由,但我在一个全新的 MVC 项目中得到了相同的行为。
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 },
new[] { "AreaProblem.Areas.Admin.Controllers" }
);
}
}
public class RouteConfig
{
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 }
);
}
}
在此屏幕截图中,"root level" 处的控制器的意思是 Controllers/HomeController
。我希望不以 /admin
开头的 URL 只查看那些控制器。问题是它 也在 中搜索 Areas/Admin/Controllers
。
因此 MVC 路由引擎将在不同的命名空间中查找以尝试找到匹配的控制器。您可以通过指定命名空间来解决此问题(就像您为管理区域所做的那样)。您还可以指定路由不使用 DataTokens 搜索其他命名空间。
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new [] { "AreaProblem.Controllers" }
).DataTokens["UseNamespaceFallback"] = false;
我的 MVC 应用程序设置了 root/global 级别的控制器。这些没有明确的区域。我还有一个 "Admin" 区域。 URL以 /admin/ 开头的将被路由到管理区域中的匹配控制器。其他 URL 被路由到匹配的全局控制器。这在大多数情况下工作正常。
我遇到的问题是,如果 URL 与管理区域中的控制器匹配,而全局区域中不存在同名控制器,则请求路由错误到管理区域的控制器。我知道会发生这种情况,因为我在相关控制器中的匹配操作上设置了断点。
例如,我在管理区有一个名为CalendarController
的控制器。当我访问 /admin/calendar
时,它起作用了,因为它在 Areas/Admin/Views/Calendar/Index.cshtml
中找到了操作和相应的视图。当我访问 /calendar
时出现问题。我在根级别没有名为 Calendar 的控制器,但出于某种原因它将请求路由到我不想要的管理区域的 CalendarController
。我希望它成为 return 404,因为根级别不存在 CalendarController
。相反,我收到一个错误,因为它正在根级别(/Views/Calendar/Index.cshtml
)搜索视图,即使匹配的控制器位于管理区域。
如何防止在管理区域中搜索匹配的控制器,除非 URL 中有 /admin?
这是相关的路由代码,除了名称空间添加之外,它基本上是库存的。如果没有命名空间,问题仍然存在。实际应用中有更多的路由,但我在一个全新的 MVC 项目中得到了相同的行为。
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 },
new[] { "AreaProblem.Areas.Admin.Controllers" }
);
}
}
public class RouteConfig
{
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 }
);
}
}
在此屏幕截图中,"root level" 处的控制器的意思是 Controllers/HomeController
。我希望不以 /admin
开头的 URL 只查看那些控制器。问题是它 也在 中搜索 Areas/Admin/Controllers
。
因此 MVC 路由引擎将在不同的命名空间中查找以尝试找到匹配的控制器。您可以通过指定命名空间来解决此问题(就像您为管理区域所做的那样)。您还可以指定路由不使用 DataTokens 搜索其他命名空间。
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new [] { "AreaProblem.Controllers" }
).DataTokens["UseNamespaceFallback"] = false;