单个项目中的ASP.NET MVC区域 - 重构AreaRegistration Stuff

时间:2011-11-10 16:40:33

标签: asp.net-mvc asp.net-mvc-areas asp.net-routing

我正在尝试通过将每个Area移动到他们自己的项目中来对我的ASP.NET MVC应用程序进行molularize。一切都工作正常,直到我决定重构AreaRegistration的东西,并使用我自己的方法(这样我也可以在我的模块中注册过滤器和依赖项)。使用反射器我已设法提出以下内容。

首先,我为每个模块/区域实现以下接口:

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

E.g:

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被路由到我的Blogs模块的HomeController中的正确Action。但是它会尝试在主项目中显示Home / Index.cshtml视图,而不是模块/区域中的视图。我猜错了如何告诉视图引擎将路由URL视为一个区域,因为它似乎忽略了AreaViewLocationFormats(在RazorViewEngine中)。

如果有人能告诉我我错过了什么,我会很感激。感谢

1 个答案:

答案 0 :(得分: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);

希望这有帮助。