我刚刚意识到MVC 3和4路由可以配置路径的行动,这是一个区域的一部分,而不命名区域名称,但他们不返回视图。例如,请参阅以下代码:
namespace APS.EIMS.UI.Areas.Admin
{
public class TestController : BaseController
{
public ActionResult Index()
{
return View();
}
public JsonResult GetNames()
{
var dc = GetDataContext();
var result = from m in dc.Db<IMS_Reject>()
select new { m.Id };
return Json(result, JsonRequestBehavior.AllowGet);
}
}
}
每当我尝试//localhost/Test/Index时,它找不到Index视图,但可以将路径路由到该区域的操作(如我所期望的,它适用于//localhost/admin/Test/Index)。对于//localhost/admin/test/getnames和//localhost/test/getnames,我也得到相同的结果。为什么会这样呢?如果没有区域名称,它如何找到操作?我需要在我正在开发的应用程序中防止这种情况,这可能吗?(我的意思是路由只有当地址是完整的,否则404错误)
你可能会有一个类似默认的路由:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
因此,像//localhost/Test/Index这样的URL将与默认路由匹配,正如你所看到的,它将正确地找到控制器,但不能找到视图。默认情况下,控制器工厂将在应用程序中查找任何具有请求名称的控制器类,而不管它位于何处。
如果你显式地在默认路由中设置命名空间,并告诉MVC不要在其他命名空间中寻找控制器,就可以防止这种情况的发生。
这是通过使用MapRoute重载来完成的,它接受一个包含命名空间的字符串数组,并显式地禁用该路由的命名空间回退。(如果不禁用名称空间回退,您将只是在发现多个具有相同名称的控制器时优先考虑这些名称空间)。
可以像这样(我只设置了一个名称空间,但你可以根据需要设置多个名称空间):
Route route = routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new[] { "APS.EIMS.UI.WhateverInNoArea" }
);
route.DataTokens["UseNamespaceFallback"] = false;