38

同じソリューションに、ASP.NET MVC4 アプリケーションSlick.Appとクラス ライブラリがありますAwesome.Mvc.Lib。Awesome.Mvc.Lib には、1 つのコントローラー クラスが含まれています。

public class ShinnyController : Controller
{
    [HttpGet]
    public string Index()
    {
        return "Hello, from Awesome.Mvc.Lib";
    }
}

Slick.App から Awesome.Mvc.Lib への参照を追加するだけで、アプリケーションを実行し、ブラウザで/shinny.

これは私がまったく期待していないことです。ASP.NET MVC は、コントローラーが配置された名前空間を尊重するといつも思っていました。そのため、少なくとも私が要求しない前は、別の名前空間のコントローラーは公開されていません。

namespaces パラメータを使用するように、デフォルトのルート登録を変更しようとしました。

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        namespaces: new [] { "Slick.App.Controllers" }
    );

それでも、ShinnyController ルートは「/shinny」に引き続き一致します。

これが正しいデフォルトの動作であるという懸念があります。私の質問は、どのコントローラーが公開されているかを明示的に示し、デフォルト ルートが別のクラス ライブラリのコントローラーと一致しないようにする方法です。

4

2 に答える 2

32

ルートの名前空間リストは、リストされていない他の名前空間よりも特定の名前空間にのみ優先度を与えます。

new [] {"Namespace1", "Namespace2"}

予想されるように Namespace1 に高い優先度を与えるのではなく、両方の名前空間に他の名前空間よりも優先度を与えるだけです。

これは、リスト内の名前空間で最初にコントローラーが検索され、一致するものが見つからない場合は、その名前を持つ残りの使用可能なコントローラーが使用されることを意味します。

これを行うことで、優先順位のないコントローラーの使用を抑制することができます。

var myRoute  = routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        namespaces: new [] { "Slick.App.Controllers" }
    );

myRoute.DataTokens["UseNamespaceFallback"] = false;
于 2012-06-18T08:32:22.473 に答える
3

次のように DefaultControllerFactory から継承できます。

public class CustomControllerFactory : DefaultControllerFactory
{
    protected override Type GetControllerType(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
        var type = base.GetControllerType(requestContext, controllerName);

        if (type != null && IsIngored(type))
        {
            return null;
        }

        return type;
    }

    public static bool IsIngored(Type type)
    {
        return type.Assembly.GetCustomAttributes(typeof(IgnoreAssemblyAttribute), false).Any() 
            || type.GetCustomAttributes(typeof(IgnoreControllerAttribute), false).Any();
    }
}

次に、Global.asax にいくつかの変更を加えます

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory());
    }

そして、ここにいます!IgnoreControllerAttribute でマークされた型は表示されません。アセンブリ全体を非表示にすることもできます。

設定ベースの動作が必要な場合は、必要なすべての変更を行うことは大した問題ではありません ;)

于 2012-07-25T16:41:06.463 に答える