ASP MVC4在不同区域中具有相同名称的控制器中找到合适的方法
本文关键字:控制器 方法 MVC4 区域 ASP | 更新日期: 2023-09-27 18:27:01
我看到了一些类似的问题,但我发现我有一个不同的问题。
我有一个MVC4项目,在基础项目和3个区域中有控制器。每个区域都包含一个名为AdminController的控制器和一个方法List。
我的问题是,当我使用链接转到方法时,列表总是通过同一个控制器(例如,用户区域中的AdminController),但返回的视图是正确的。
项目结构如下:
- Mimbre.Administration(web mvc4项目)
- 区域
- 目录
- 控制器
- AdminController
- 型号
- 视图
- 管理员
- List.chtml-内容重新注册.cs
- 管理员
- 控制器
- 日志
- 控制器
- AdminController
- 型号
- 视图
- 管理员
- List.chtml
- 管理员
- 日志重新注册.cs
- 控制器
- 用户
- 控制器
- AdminController
- 型号
- 视图
- 管理员
- List.chtml
- 管理员
- 用户重新注册.cs
- 控制器
- 目录
- 控制器(基础项目)
- 视图(基础项目)
- 区域
区域注册的类包含这样的RegisterArea方法(根据当前区域使用合适的名称和命名空间):
public override void RegisterArea(AreaRegistrationContext context) {
context.MapRoute(
"Contents_default",
"Contents/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "Mimbre.Administration.Areas.Contents.Controllers" }
);
}
Global.asax包含为基础项目注册路由的方法
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[]{"Mimbre.Administration.Controllers"}
);
}
在index.chtml(在基础项目中)中,我创建了每个区域的List方法的链接:
<a href="@Url.Action("List", "Admin", new { area = "Contents"})" >Contents list</a>
<a href="@Url.Action("List", "Admin", new { area = "Logs"})" >Logs list</a>
<a href="@Url.Action("List", "Admin", new { area = "Users"})" >Users list</a>
在生成的html中,这些链接如下所示:
<a href="/Contents/Admin/List/">Contents list</a>
<a href="/Logs/Admin/List/">Logs list</a>
<a href="/Users/Admin/List/">Users list</a>
我认为这些链接是正确的,问题是任何点击的链接都会带我通过用户的AdminController区域中的方法List,而其他区域的AdminController中的方法列表从未被选中。
这个问题可以通过重命名控制器的名称来解决,每个区域都有唯一的名称,但我真的需要在所有区域保持相同的控制器名称,知道吗???
提前感谢!!!
最后我可以模拟您的问题了。我可以获得与您相同输出的唯一方法(无论您试图访问哪个区域,但到达相同的用户控制器并以正确的视图进行响应)是当您使用错误的控制器名称空间注册区域时。
/管理员/主页/列出路线:
namespace SandboxMvcApplication.Areas.Admin.Controllers
{
public class HomeController : Controller
{
public ActionResult List()
{
ViewBag.Message = "You've acessed Admin/List";
return View();
}
}
}
/管理员/主页/列表视图:
@{
ViewBag.Title = "List";
}
<h1>Admin</h1>
<h2>@ViewBag.Message</h2>
管理区域注册:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "SandboxMvcApplication.Areas.Admin.Controllers" }
);
}
/用户/主页/列表路线:
public class HomeController : Controller
{
public ActionResult List()
{
ViewBag.Message = "You've accessed User/List";
return View();
}
}
/用户/主页/列表视图:
@{
ViewBag.Title = "List";
}
<h1>User</h1>
<h2>@ViewBag.Message</h2>
用户区域注册:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"User_default",
"User/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "SandboxMvcApplication.Areas.Admin.Controllers" }
);
}
有了这个配置,我的输出是:
/管理员/主页/列出
管理员
您已访问管理员/列表
/用户/主页/列出
用户
您已访问管理员/列表
请注意,第一个单词很好用(确保呈现了正确的视图,但从列表操作中混合了错误的数据)。
如果我在UserAreaRegistration("SandboxMvcApplication.Areas.user.Controllers")中更正了用户控制器命名空间,一切都很好!
看看这是否能对你有所帮助,或者尝试将你的名称空间显式地放在正确的控制器上。您还可以检查Admins控制器是否也具有正确的命名空间。
您需要在路线注册中再添加一个设置。这将防止DefaultControllerFactory在非预期区域中搜索控制器。
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[]{"Mimbre.Administration.Controllers"}
).DataTokens["UseNamespaceFallback"] = false;