10

これまでのところ(簡潔にするために)私はglobal.asaxに次のように登録された1つのルートを持っています:

routes.Add(new LowercaseRoute("{action}/{id}", new MvcRouteHandler())
  {
    Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = UrlParameter.Optional }),
    DataTokens = rootNamespace
  }); 

「rootNamespace」は

var rootNamespace = new RouteValueDictionary(new { namespaces = new[] { "MyApp.Web.Controllers" } });

LowercaseRouteはRouteを継承し、すべてのパスを小文字にします。私もこのように登録されたエリアを持っています:

context.Routes.Add(new LowercaseRoute("admin/{controller}/{action}/{id}", new MvcRouteHandler())
  {
    Defaults = new RouteValueDictionary(new { action = "List", id = UrlParameter.Optional }),
    DataTokens = adminNamespace
  });

adminNamespaceが別の名前空間である場合、デフォルトルートと同じ考えですが、正しい名前空間を使用します。これは正常に機能します。次のようなURLにアクセスできます。

http://example.com/contact  <- default route, "Home" controller
http://example.com/admin/account  <- area route, "Account" controller, default "List" action

問題はこれが

http://example.com/admin/home/contact

また動作します。「管理者」エリアの下に「連絡」アクションを持つ「ホーム」コントローラーはありません。「/contact」から正しいページを取得しますが、URLは「/ admin / home/contact」です。

これを防ぐ方法はありますか?

ありがとう。

4

1 に答える 1

18

AreaRegistrationContext.MapRouteのコードを見てください。

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;
}

特に、デフォルトでfalseに設定されているUseNamespaceFallbackトークンに注意してください。検索をエリアの名前空間に制限する場合は、同様のロジックが必要です。(True =現在の名前空間でコントローラーを検索し、失敗するとすべての名前空間を検索します。False=現在の名前空間のみを検索します。)

于 2011-01-06T09:06:43.080 に答える