ソースの分析——ASP.Net MVCの中で、Global.asaxの中でどのようにArea内部を指すデフォルトのRouteを配置しますか?
ASP.Net MVCにRouteを設定するとデフォルトのRouteを設定できます.たとえば私は入力します.http://localhostに入るときはデフォルトで入力します.http://localhost/home/index.Global.asaxでこのように配置できます.
しかし、もしあなたがデフォルト値をArea内部のController/アクションに指したいなら、どうすればいいですか?
上の例をまねて、私はこうします.
MyAreaというaraを新たに作って、ルートを設定します.
運転してみます.
結果はControllerの衝突で、スクリーンショットは以下の通りです.
これは私達が配置したあの‘Area’が機能していないと説明しています.MVCのrouteはAreaをサポートしていませんでした.
MyArea Registrationのソースコードを見に来ました.
私達はView Engineのソースコードの中で原因を探して、肝心なコードはViewを探している時の下のいくつかの文です.
振り返ってみます.私の前に貼ってあるMyAreearegistrationのソースコードを見てください.
この点が分かりました.私たちは引き続きrouteを登録するところを改造できます.
実際のプロジェクトでは、Area内部の一つのアクションに対してデフォルトのrouteを直接指す可能性が低いです.でも特殊なシーンがあります.
このような特殊なシーンを実現する試みを通して、AReaRegistrationの動作原理を分析し、RouteとView EngineがAreaをどのように処理しているかを探ってみました.
MVCはできるだけ少なくフレームに侵入した場合に、Area機構のセットを実現することが見られます.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
は簡単ですよね.しかし、もしあなたがデフォルト値をArea内部のController/アクションに指したいなら、どうすればいいですか?
上の例をまねて、私はこうします.
MyAreaというaraを新たに作って、ルートを設定します.
routes.MapRoute(
"Default", // Route name
"{area}{controller}/{action}/{id}", // URL with parameters
new {area = "MyArea", controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
にアリーナのセレクションを追加しました.いいですよね.運転してみます.
結果はControllerの衝突で、スクリーンショットは以下の通りです.
これは私達が配置したあの‘Area’が機能していないと説明しています.MVCのrouteはAreaをサポートしていませんでした.
MyArea Registrationのソースコードを見に来ました.
public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) {
if (namespaces == null && Namespaces != null) {
namespaces = Namespaces.ToArray();
}
Route route = Routes.MapRoute(name, url, defaults, constraints, namespaces);
route.DataTokens["area"] = AreaName;
// disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up
// controllers belonging to other areas
bool useNamespaceFallback = (namespaces == null || namespaces.Length == 0);
route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback;
return route;
}
それはMapRouteの時にnamespaceの制約を加えた.私たちも加えてみます. routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new[] { "WebArchDemo.Areas.MyArea.*" }
);
はい、成功しました.でも、よく見てください.Viewが間違っています.それは意外にもやはりAreaの外のViewを探して、このAreaの下のViewではありません.私達はView Engineのソースコードの中で原因を探して、肝心なコードはViewを探している時の下のいくつかの文です.
string areaName = AreaHelpers.GetAreaName(controllerContext.RouteData);
bool usingAreas = !String.IsNullOrEmpty(areaName);
List viewLocations = GetViewLocations(locations, (usingAreas) ? areaLocations : null);
View Engineはcontroller Conttext.RouteDataの中でArea Nameを探します.見つけたらAreaの中のViewを使います.そうでなければルートディレクトリの下のViewを使います.このArea NameはいつRouteDataの中に置いたのですか?振り返ってみます.私の前に貼ってあるMyAreearegistrationのソースコードを見てください.
route.DataTokens["area"] = AreaName;
AreaのRouteを登録する時、このArea Nameを入れます.この点が分かりました.私たちは引き続きrouteを登録するところを改造できます.
var route = routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new[] { "WebArchDemo.Areas.MyArea.*" }
);
route.DataTokens["area"] = "MyArea";
完全に正しいです.実際のプロジェクトでは、Area内部の一つのアクションに対してデフォルトのrouteを直接指す可能性が低いです.でも特殊なシーンがあります.
このような特殊なシーンを実現する試みを通して、AReaRegistrationの動作原理を分析し、RouteとView EngineがAreaをどのように処理しているかを探ってみました.
MVCはできるだけ少なくフレームに侵入した場合に、Area機構のセットを実現することが見られます.