【发布时间】:2017-08-14 13:01:41
【问题描述】:
假设我们在 MVC4 项目中有两个控制器 ControllerA 和 ControllerB,如下所示:
Controllers
|
\- MvcApi
| |
| \- ControllerB.cs
|
\- ControllerA.cs
这个概念是 ControllerB 是一个 mvc 控制器,但是它纯粹通过 ajax 调用来提供 html-razor-partial-views。另一方面,ControllerA 是一个接地气的 mvc 控制器。在 RouteConfig.cs 我们有:
public class MvcRouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "MvcApi",
url: "mvcapi/{controller}/{action}/{id}",
defaults: new { id = UrlParameter.Optional },
namespaces: new[] { typeof(BController).Namespace } //<- "Project.Views.MvcApi"
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "AController", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { typeof(AController).Namespace } //<- "Project.Views"
);
}
}
我们现在尝试自动生成一个指向 AController 动作的 url,如下所示:
@(Url.RouteUrl(routeValues: new { controller = "A", action = nameof(AController.SomeActionNameHere) }))
鉴于上面显示的配置,我们预计上面的语句会导致:
"/A/SomeActionNameHere"
然而我们得到的是:
"/mvcapi/A/SomeActionNameHere"
这当然在运行时有效,但它完全具有误导性(“仅仅因为它在工作并不意味着它是正确的”)。我们可以通过明确指定路由名称来强制执行所需的行为:
@(Url.RouteUrl(
routeName: "Default", // <- this "fixes" the issue
routeValues: new { controller = "A", action = nameof(AController.SomeActionNameHere) })
)
这确实返回了所需的网址:
"/A/SomeActionNameHere"
然而,我对 asp.net 基础设施如此容易堵塞并最终需要如此多的“手持”才能确定 AController 直接位于“Views”命名空间下而不是在“Views.MvcApi”下。人们会期望发出一个简单的:
@(Url.RouteUrl(routeValues: new { controller = "A", action = nameof(AController.SomeActionNameHere) }))
会立即自动神奇地返回正确的网址。怎么回事?
附录:我还检查了项目的 2 个 web.config 文件,没有发现任何可疑之处。如果您认为我可能有什么问题,我会用所需的 sn-ps 更新这篇文章,供您检查。
【问题讨论】:
标签: c# asp.net asp.net-mvc razor routes