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

C# 构建两个不同的网站,其中外部页面不同,内部页面相同,c#,asp.net-mvc,visual-studio-2010,asp.net-mvc-3,C#,Asp.net Mvc,Visual Studio 2010,Asp.net Mvc 3,我有一个ASP.NETMVC网站,“在线学习普通话”。它是可操作的,对我来说很好。现在,我想重新使用这个网站作为新网站“在线学习西班牙语”的模板。这两个网站将位于完全不同的域和完全不同的服务器上 对于我的“在线学习汉语”网站,1/3的网页是外部页面,用户无需登录该网站即可浏览其他2/3的网页是内部网页,用户只有登录到网站才能看到这些网页。我希望两个网站使用不同的外部页面(两个网站的外部.aspx页面将不同),但两个网站共享相同的内部页面集(两个网站的内部.aspx页面将相同) 我的问题是,在AS

我有一个ASP.NETMVC网站,“在线学习普通话”。它是可操作的,对我来说很好。现在,我想重新使用这个网站作为新网站“在线学习西班牙语”的模板。这两个网站将位于完全不同的域和完全不同的服务器上

对于我的“在线学习汉语”网站,1/3的网页是外部页面,用户无需登录该网站即可浏览其他2/3的网页是内部网页,用户只有登录到网站才能看到这些网页。我希望两个网站使用不同的外部页面(两个网站的外部.aspx页面将不同),但两个网站共享相同的内部页面集(两个网站的内部.aspx页面将相同)

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

// 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页面,另一个是学习西班牙语在线网站的.aspx文件。这是构建我的项目的最佳方式还是有更干净的方式


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

嗯,我在某种程度上同意@Haney的观点。这实际上取决于网站中受汉语/西班牙语保护的部分有多不同。一般来说,受保护和未受保护区段之间的划分很简单。只有登录用户才能使用的控制器/操作应使用
[Authorize]
属性进行保护。例如,要将只注册普通话的用户限制在普通话部分,可以使用角色。例如,将用户分配到“普通话”角色,然后指定只有该角色中的用户才能访问该角色:
[授权(Roles=“mandarn”)]


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

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

接下来,我需要注册我的“在线学习西班牙语”主页的路由,以覆盖我的“在线学习汉语”主页的路由。创建SpanishTutor区域时,将创建一个名为SpanishTutorareRegistration.cs的.cs文件。在该文件中,将以下代码添加到RegisterArea(…):

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

在我的web.config中,添加以下内容(我可以将其更改为“在线学习普通话”网站的“普通话导师”):



这正是创建MVC区域功能的真正目的!那么,你是说我的外部页面应该在区域下,而我共享的内部页面不应该在区域下?我不熟悉使用区域,因此如果我没有跟上速度,我深表歉意(我正在阅读关于它的教程)。您可以创建一个属性,根据网站域或其他因素设置区域RequestContext数据,然后将页面放置在您认为合适的位置。好的,让我学习RequestContext以及如何将其应用于区域。另外,如果有人能提供Haney建议的更详细的答案,我将不胜感激,因为我正试图弄清楚如何使用Areas和RequestContext来解决我的问题,而我是新使用Areas和RequestContext的人。谢谢Chris。我想出来了。请看我发布的解决方案。谢谢你的帮助!
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
    );
  }
}
 <add key="WebsiteType" value="spanishtutor" />