构建两个不同的网站,外部页面不同,内部页面相同

Structure two different websites where external pages are different, internal pages are same

我有一个 ASP.Net MVC 网站,"learning Mandarin online"。它正在运行,对我来说工作正常。现在,我想重新使用此网站作为新网站的模板,"learning Spanish online." 两个网站将位于完全不同的域和完全不同的服务器上。

对于我的"learning Mandarin online"网站,1/3的网页是外部页面,用户无需登录网站即可浏览另外 2/3 的网页是 内部 页面,用户只有登录网站才能看到这些页面。我希望两个网站使用不同的外部页面(两个网站的外部 .aspx 页面将不同)但是两个网站共享同一组内部页面(两个网站的内部 .aspx 页面相同)。

我的问题是,在 ASP.Net MVC 中,如何为两个网站构建 project/solution?由于两个网站的唯一区别是外部页面,我能想到的处理外部页面的最简单解决方案是将每个视图的映射存储在数据库中,根据一些常量(即 WebsiteType)从数据库中获取此映射在web.config中设置,然后根据映射返回视图。例如,在我的控制器中:

// WebsiteType is stored in web.config.  It is set to LearnMandarin for the learn Manadarin
// online website and it is set to LearnSpanish for the learn Spanish online website
string websiteType = WebConfigurationManager.AppSettings["WebsiteType"];

// figure out which Homepage .aspx view to return, based on the websiteType
// GetView(...) will get the mapping from the database
string viewToReturn = GetView(websiteType, "HomepageView");

return View(viewToReturn);

这是目前为止我能想到的最干净的解决方案,也是我能想到的最好的结构。我最终会在同一个目录中有两个不同的 .aspx 文件 - 一个用于学习普通话在线网站的 .aspx 页面,一个用于学习西班牙语在线网站的 another.aspx 文件。这是构建我的项目的最佳方式还是有更简洁的方式?

(我使用的是 Visual Studio 2010 和 ASP.Net MVC 版本 3.0.0.0)

好吧,我在某种程度上同意@Haney 的观点。这实际上取决于站点的 Mandarin/Spanish 受保护部分的不同程度。通常,受保护和未受保护部分之间的划分很简单。 Controllers/Actions 仅对登录用户可用,应使用 [Authorize] 属性进行保护。例如,要将仅注册普通话的用户限制在普通话部分,您可以使用角色。例如,将用户分配给 "Mandarin" 角色,然后指定只有该角色中的用户才能访问它:[Authorize(Roles = "Mandarin")].

开始变得更加不确定的是普通话和西班牙语部分之间的区别。对于大多数事情,您实际上可以将语言作为路由参数。换句话说,所有普通话页面都会有 URL,比如 /mandarin/some/page/,而西班牙语页面会有 URL,比如 /spanish/some/page/。然后,您可以使用路由参数来切换布局、在操作或视图内分支等。但是,如果这两个部分之间有很多差异,所有这些分支可能会导致一些复杂的代码。如果是这种情况,那么将每种语言创建为一个单独的区域可能更合适。每个区域都会有一个隔离的路由方案,即如果您的区域被命名为 Mandarin,那么该区域中的每个控制器操作都会自动在 URL 下,例如 /mandarin/some/page/。您不必捕获路线的 "mandarin" 部分来确定游戏中的语言:只需在该区域内点击控制器动作,您就会知道。但是,这种方法的缺点是最终可能会出现一些代码重复。您可以通过控制器和视图继承来防止其中的大部分,但在某些情况下,您仍然会以两个区域中存在的非常相似的代码结束。

我或多或少使用了 Haney 建议的区域。我在我的项目中创建了一个名为 SpanishTutor 的区域。创建该区域后,它将具有与典型 ASP.Net MVC 项目相同的控制器和视图文件夹结构(但它们都位于 Areas 子文件夹下)。我认为我的主页是我的 "external" 页面之一。因此,我在 SpanishTutor 区域的 "controller" 文件夹中创建了一个 HomeController.cs 文件。对于这个 HomeControllers.cs 文件,我必须将命名空间更改为 "Tutors.Areas.SpanishTutor.Controllers",这样它就不会与现有的 HomeController.cs 文件冲突。我还在我的 SpanishTutor 区域的 "views" 文件夹下创建了一个带有 Index.aspx 的主文件夹。

接下来,我需要为我的 "learn Spanish online" 主页注册路由以覆盖我的 "learn Mandarin online" 主页的路由。当您创建 SpanishTutor 区域时,会创建一个名为 SpanishTutorAreaRegistration.cs 的 .cs 文件。在该文件中,将以下代码添加到 RegisterArea(...):

public override void RegisterArea(AreaRegistrationContext context)
{

  string websiteType = WebConfigurationManager.AppSettings["WebsiteType"];

  if (websiteType.Contains("spanishtutor"))
  {
    context.MapRoute(
        "SpanishTutor_Root", // Route name
        "", // override the homepage
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
        new[] { "Tutors.Areas.SpanishTutor.Controllers" } // namespace so there is no conflict with the namespace of the original homeapge
    );
  }
}

如果您有更多的外部网页,您可以像首页一样添加每个外部网页。对我来说,没有必要修改 Global.asax.cs.

在我的web.config中添加以下内容(对于"learn Mandarin online"网站我可以将其更改为"mandarintutor"):

 <add key="WebsiteType" value="spanishtutor" />