【问题标题】:Structure two different websites where external pages are different, internal pages are same构建两个不同的网站,外部页面不同,内部页面相同
【发布时间】:2017-01-26 14:48:41
【问题描述】:

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

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

【问题讨论】:

  • 这就是MVC的Area特性的真正目的!
  • 那么,您是说我的外部页面应该在区域下,而我共享的内部页面不应该在区域下吗?我是使用区域的新手,所以如果我没有跟上速度,我深表歉意(我现在正在阅读它的教程)。
  • 您可以创建一个属性来根据网站域或其他因素设置 Area RequestContext 数据,然后将页面放置在您认为合适的位置。
  • 好的,很酷 让我研究一下 RequestContext 以及如何将它应用到区域。此外,如果有人可以提供 Haney 建议的更详细的答案,那将不胜感激,因为我试图弄清楚 Areas 和 RequestContext 如何都可以用来解决我的问题,而且我是使用 Areas 和 RequestContext 的新手。

标签: c# asp.net-mvc visual-studio-2010 asp.net-mvc-3


【解决方案1】:

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

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

【讨论】:

  • 谢谢克里斯。我想到了。请查看我发布的解决方案。感谢您的帮助!
【解决方案2】:

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

接下来,我需要为我的“在线学习西班牙语”主页注册路由,以覆盖我的“在线学习普通话”主页的路由。当您创建 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" />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-13
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    相关资源
    最近更新 更多