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

问题描述:

我有一个ASP.Net MVC网站,“在线学习普通话”。它运作良好,对我来说工作得很好。现在,我想重新使用此网站作为新网站的模板,“在线学习西班牙语”。这两个网站将位于完全不同的域和完全不同的服务器上。结构两个不同的网站,外部页面不同,内部页面相同

对于我的“学习中文在线”网站上,网页1/3是外部页面,用户可以浏览,而无需登录到网站其他2/3的网页是内部页面,用户只能看到他们是否登录到网站。我希望这两个网站都使用不同的外部网页(两个网站的外部.aspx页面将不同),但是两个网站共享同一组内部网页(两个网站的内部.aspx页面将相同)。

我的问题是,在ASP.Net MVC中,我怎样才能为两个网站构建我的项目/解决方案?由于两个网站的唯一区别是外部页面,我能想到的处理外部页面的最简单的解决方案是将每个视图的映射存储在数据库中,根据某个常量(即。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)

+0

这真的是什么*区* MVC的功能有被创造了! – Haney

+0

那么,你是说我的外部网页,应该在区域下面,而我的内部网页是共享的,不应该在区域下面?我是使用区域的新手,所以如果我的速度不够快,我很抱歉(我正在阅读它的教程)。 –

+0

您可以根据网站域或其他因素创建一个属性来设置Area RequestContext数据,然后将页面放在您认为合适的位置。 – Haney

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

接下来,我需要注册我的“学习西班牙语在线”主页的路由,以覆盖我的“学习汉语在线”主页的路由。在创建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中添加以下(我可以将其更改为“mandarintutor”为“学习中文在线”网站):

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

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

在哪里开始得到更多iffy与普通话和西班牙语部分之间的区别。对于大多数情况,您可以将语言作为路由参数。换句话说,所有的普通话网页都会有一个类似于/mandarin/some/page/的URL,而西班牙语网页则会有一个类似于/spanish/some/page/的URL。然后,您可以使用route参数来切换布局,在动作或视图中进行分支等。但是,如果这两个部分之间存在很大差异,则所有这些分支都可能导致一些复杂的代码。如果情况变得如此,那么将每种语言创建为一个单独的区域可能更合适。每个区域都会得到一个独立的路由方案,也就是说,如果您的区域名称为Mandarin,那么该区域中的每个控制器操作都将自动处于一个URL,如/mandarin/some/page/。您不必捕捉路线中的“普通话”部分来确定游戏中的语言:只需在该区域内触击控制器操作,您就会知道。但是,这种方法的缺点是可能会导致代码重复。您可以通过控制器阻止大部分操作并查看继承,但可能会出现这种情况,即您仍然以两个区域中存在非常类似的代码结束。

+0

谢谢克里斯。我想到了。请看看我发布的解决方案。谢谢你的帮助! –