在 Global.asax 文件中为默认路由添加 NameSpace。
var route = routes.MapRoute(
"Default", // Route name
"{controller}/{action}", // URL with parameters
new { controller = "Home", action = "Index" }, // Parameter defaults,
new[] { "YourNameSpace.Controllers" }
);
在Area 中的AreaRegistration 类中添加命名空间
public class MyArea : AreaRegistration
{
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"test",
"Test/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new[] { "MyProjectNameSpace.Controllers" }
);
}
}
说明
我的申请中有以下区域。所以下面突出显示的部分与控制器无关。好的。
图-1
我输入了网址:http://localhost:2474/ActionFilterAttribute/index
在前往目的地之前。我将向您展示我是如何初始化测试的。我添加了 RoureDebugger. You can get the Dll from this location 的参考。然后我在Application_StartHandler 下的 Global.asax 文件中添加了一行代码。
RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
所以,最后使用上面提到的Url,我开始调试应用程序。终于看到下图了。
图-2
问题
动作仍然被调用,虽然没有找到视图所以我得到一个错误。
回答
因此,如果您注意上面突出显示的Route,那么,这就是Default Route。如上所述,此模式与 Url 匹配。但是在这种情况下将找不到 View,这就是您的 Controller Action Method 被调用的原因。
在进入下一部分之前,我为什么会得到 404。我将向您展示我在示例应用程序中所做的一些测试。
我创建了一个派生自ActionFilterAttribute 的类,如下所示。这仅包含一个名为OnResultExecuting 的Override。这个Handler在执行特定Action对应的View之前执行
创建这个类的目的只是为了验证RouteData 和DataTokens 发生了什么。
public class MyActionFilter : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var viewResult = filterContext.Result as ViewResult;
if (viewResult != null)
{
var razorEngine = viewResult
.ViewEngineCollection
.OfType<RazorViewEngine>()
.Single();
var viewName = !String.IsNullOrEmpty(viewResult.ViewName) ?
viewResult.ViewName :
filterContext.RouteData.Values["action"].ToString();
var razorview = razorengine
.FindView
(
filtercontext.Controller.ControllerContext,
viewname,
viewResult.MasterName,
false
).View as RazorView;
}
base.OnResultExecuting(filterContext);
}
}
好的。让我们回到最初的问题。为什么我得到 404?
在检查Area Route 之前,您的Controller 将被默认基本路由{controller}/{action} 拾取,因此将在Root/Views 中而不是Area/views 中查找View。
为了检查这一点,我在Area内部Controller的Action Method中设置了调试器,发现当Requested url没有Area Name时,没有DataToken信息。让我们在Debug 模式中查看有关DataToken 的更多详细信息
图-3
如果你注意ControllerContext,我列举了DataTokens,它没有显示键/值。这是因为在Root Directory 下找不到与该控制器相关的视图
你怎么能说当前所在的目录是根目录呢?证明如下
图-4
RouteData 值中没有提到命名空间或任何区域。对吧?
现在让我们转到与包含Area Name 的模式匹配的RouteData。所以,这次我的 Url 是:http://localhost:2474/mypractise/ActionFilterAttribute/index 以下是与 URLRoutingModule
匹配的
RouteData
图-5
请注意突出显示的部分,这次匹配的路由属于AreaName 模式,对于属于根目录中某个RouteData 的默认路由,匹配值为false。对吧?
如果出现上述请求的 URL,我对 DataTokens 的最终详细信息。这次可以看到 Namespace 详细信息和 Area 详细信息。
图-6
结论:
当Controller 位于区域内且您的DataTokens 未显示Area、NameSpace 和UseNameSpaceFallback 的信息时。这意味着您将获得 404。如图 4 中所述,您请求的 Url 是正确的,因此您获得了 DataTokens 并且如图 3 中所述,DataTokens 未显示,因为请求的 Url 不包含 Area Name 和尽管您已经获得了图 2 中提到的 RouteData,因为它是默认的 Url 模式。最后尝试执行OnResultExecuting中的第三行代码。它将显示 null,因为未找到 View。
希望这个解释对你有所帮助。