簡體   English   中英

ASP.NET MVC4在錯誤的區域中搜索控制器

[英]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之前執行

創建此類的目的只是為了驗證RouteDataDataTokens發生了什么。

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?

您的Controller將被默認基本路線有所回升{controller}/{action}在檢查前, Area Route ,因此會尋找ViewRoot/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沒有顯示AreaNameSpaceUseNameSpaceFallback信息的信息。 這意味着您將得到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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM