0

各エリアを独自のプロジェクトに移動して、ASP.NET MVC アプリケーションをモジュール化しようとしています。AreaRegistration のものをリファクタリングして独自のアプローチを使用することを決定するまで、すべてが正常に機能していました (この方法で、モジュール内にフィルターと依存関係を登録することもできます)。リフレクターを使用して、次のことを思いつきました。

最初に、各モジュール/領域に次のインターフェイスを実装します。

public interface IModule {
    string ModuleName { get; }
    void Initialize(RouteCollection routes);
}

例えば:

public class BlogsModule : IModule {
    public string ModuleName { get { return "Blogs"; } }

    public void Initialize(RouteCollection routes) {
        routes.MapRoute(
            "Blogs_Default",
            "Blogs/{controller}/{action}/{id}",
            new { area = ModuleName, controller = "Home", action = "Index",
                id = UrlParameter.Optional },
            new string[] { "Modules.Blogs.Controllers" }
        );
    }
}

次に、Global.asax ファイル (Application_Start イベント) で次のように言います。

// Loop over the modules
foreach (var file in Directory.GetFiles(Server.MapPath("~/bin"), "Modules.*.dll")) {
    foreach (var type in Assembly.LoadFrom(file).GetExportedTypes()) {
        if (typeof(IModule).IsAssignableFrom(type)) {
            var module = (IModule)Activator.CreateInstance(type);
            module.Initialize(RouteTable.Routes);
        }
    }
}

次に、既存の AreaRegistration のものを削除しました。この時点まで、すべてが正常に機能しています。アプリケーションを実行してモジュールへのリンクをレンダリングすると、次のようになります。

@Html.ActionLink("Blogs", "Index", "Home", new { area = "Blogs" }, null)

正しい URL が表示されますが、URL をクリックすると間違ったビューが表示されます。デバッグ後、ブログ モジュールの HomeController 内の正しいアクションに URL がルーティングされているように見えます。ただし、モジュール/エリアのビューではなく、メイン プロジェクトの Home/Index.cshtml ビューを表示しようとします。AreaViewLocationFormats(RazorViewEngine内)を無視しているように見えるため、ルーティングされたURLをエリアとして扱うようにビューエンジンに指示する方法を見逃した行のどこかを推測しています。

誰かが私に欠けているものを見せてくれれば幸いです。ありがとう

4

1 に答える 1

0

さらにリファクタリングすると、ビュー エンジンはエリア データ トークンを探すように見えます。したがって、モジュールの Initialize メソッドにルートを追加するようにコードを次のように変更しました。

// Create the route
var route = new Route("Blogs/{controller}/{action}/{id}", new RouteValueDictionary(new { area = ModuleName, controller = "Home", action = "Index", id = UrlParameter.Optional }), new MvcRouteHandler());

// Add the data tokens
route.DataTokens = new RouteValueDictionary();
route.DataTokens["area"] = this.ModuleName;
route.DataTokens["UseNamespaceFallback"] = false;
route.DataTokens["Namespaces"] = new string[] { "Modules.Blogs.Controllers" };

// Add the route
routes.Add(route);

お役に立てれば。

于 2011-11-14T13:02:11.107 に答える