[英]ASP.NET MVC4 Searching for controller in wrong area
我正在使用默認的MVC路由設置:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );
我將區域定義為:
public class AdministrationAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Administration";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Administration_default",
"Administration/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
我在那個區域有一個控制器:
namespace XXX.Areas.Administration.Controllers
{
public class CountryController : Controller
{
public ActionResult Index()
{
///
}
}
}
當我輸入
/行政/國家
它按照需要工作得很好。
當我輸入
/國家
動作仍然被調用,雖然找不到視圖所以我收到錯誤。
為什么MVC接受
/國家
作為有效路線? 我在非區域區域沒有另一個CountryController。
在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
類中添加NameSpace
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
我鍵入了Url: http://localhost:2474/ActionFilterAttribute/index
在前往目的地之前。 我將向您展示我如何初始化我的測試。 我添加了RoureDebugger的參考。 你可以從這個位置獲得Dll 。 然后我在Application_Start
Handler下的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);
}
}
您的Controller
將被默認基本路線有所回升{controller}/{action}
在檢查前, Area Route
,因此會尋找View
的Root/Views
,而不是在Area/views
。
為了檢查這一點,我在區域內的Controller的Action方法中設置了調試器,發現當Requested url沒有Area Name
時沒有DataToken
信息。 讓我們在Debug
模式下看到有關DataToken
的更多細節
圖-3
如果你注意ControllerContext
,我枚舉了DataTokens
,它沒有顯示鍵/值。 這是因為Root Directory
下沒有找到與該控制器有關的視圖
怎么說現在的目錄是根目錄? 證明如下
圖-4
RouteData
值中沒有提到Namespace或任何Area。 對?
現在讓我們轉到與包含Area Name
的模式匹配的RouteData
。 所以,這次我的Url是: http://localhost:2474/mypractise/ActionFilterAttribute/index
以及以下是與URLRoutingModule匹配的RouteData
圖-5
請注意突出顯示的部分,這次Route匹配屬於AreaName
模式,默認路由的匹配值為false,屬於Root Directory中的某些RouteData
。 對?
在上述請求的Url的情況下,我的DataTokens
最終細節。 您可以在此次查看命名空間詳細信息和區域詳細信息。
圖-6
結論 :
當Controller
在Area中時,您的DataTokens
沒有顯示Area
, NameSpace
和UseNameSpaceFallback
信息的信息。 這意味着您將得到404.如圖4所示,您請求的Url是正確的,因此您獲得了DataTokens
,如圖3所示,DataTokens未顯示,因為請求的Url不包含Area Name
,盡管事實上你有如圖2所示的RouteData
,因為它是一個默認的Url模式。 最后嘗試在OnResultExecuting
執行第三行代碼。 它將顯示null,因為找不到View。
希望這個解釋能幫到你。
核實。 修改Global.ascx.cs文件中的默認路由,如下所示。
var route = routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "APPLICATION_NAMESPACE.Controllers.*" }
);
route.DataTokens["UseNamespaceFallback"] = false;
編輯:
我很抱歉。 這似乎是你不想要它做的這個問題,以及知道為什么 。
您遇到的問題是默認路由將查找任何控制器。 即使它在一個區域。 您可以通過簡單地將namespaces
參數添加到路由來克服此默認行為,並指定默認路由應該使用控制器查找的內容。
如果您不想提供區域外部區域的視圖,我上面提供的解決方案僅僅是一個修復。
還有為什么這是發生一個偉大的文章在這里 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.