DotNetNuke网站

分享于 

15分钟阅读

Web开发

  繁體

介绍

我将一个大站点的一部分迁移到了 DotNetNuke,这是一个开源的高级 CMS。 迁移后,每个页面的加载速度非常慢。 经过调查,我发现 SiteMap ( TreeView 控件) 是时间延迟的来源。 所以我测试了另外三个 SiteMap 控件在网上发现了。 结果都是一样的结果太慢了。 我的第一个想法是 500页的阅读是耗时的。 然后,我们就完成了一个测试程序,发现从数据库中读取的数据已经完成,并且在没有时间的情况下完成了树的数据结构,甚至是 2.0站点 TreeView 控件的填充非常快。 瓶颈是 TreeView web控件的呈现。 我假设另一个更慢,SiteMap 总是填充完整树,然后使 TreeView 控件呈现那么长,即使大多数节点折叠。 这是我的想法,因为你通常只有一小部分树,你只是不需要来自它的他叶子的数据。 如果用户展开一个节点,那么我将从数据库中获取子节点并填充一个节点。 DnnSiteMap的另一个特性是在哪个页面上,它被称为 to,它是一个选项卡,并且扩展它自己。

重要:DnnSiteMap 仅适用于 DotNetNuke 4和 APS.NET 2.0 ! 对于安装,你必须遵循安装指令( 请参见下面)。

背景

是一个开源的内容管理系统。 它是从IBuySpyPortal派生的,这是微软的最佳实践,它展示了 ASP.NET的功能。 目前,DotNetNuke ( DNN )的版本是 4,它基于新的ASP.NET 2.0,并以 VB.Net 编程。 由于它的巨大的社区支持,微软支持DNN项目。 DNN由一个核心团队,Walker带领。

功能

  • 快速 SiteMap,因为树只是按需填充,从数据库中。
  • root 选项卡( 页面) 可以通过设置定义。
  • 显示行可以通过设置设置。
  • 可以通过设置设置节点文本文字换行。
  • 预定义的icon 集( 包括许多) 可以通过设置设置。
  • Panel 控件( 折叠全部/展开全部/当前) 可以通过设置显示或者隐藏。
  • 如果只有标签可见,用户才有权限查看标签。
  • 可以通过设置设置节点缩进以像素为单位。

使用代码

我对代码的inline 进行了注释,以便任何人都能理解每个步骤做什么。 基本上,代码是直接。 在App_Code文件夹中,所有数据和业务逻辑都在文件夹中,而UI代码位于 ViewDnnSiteMap.ascx.cs 文件中。

在数据层,你可以找到以下函数:

///<summary>/// Gets all tabs that have no ParentId /// and are not deleted and visible///</summary>///<returns>IDataReader: TabId (int), TabName (string), /// Children (int)</returns>publicabstract IDataReader GetRootNodesFromDb();///<summary>/// Gets all tabs that are children of the specified tab///</summary>///<paramname="parentTabId">TabId of the parent tab</param>///<returns>IDataReader: TabId (int), TabName (string), /// Children (int)</returns>publicabstract IDataReader GetChildNodesFromDb(int parentTabId);///<summary>/// Gets parent tab for specified tab///</summary>///<paramname="childTabId">TabId of the child tab</param>///<returns>IDataReader: ParentTabId (int), ParentName (string);/// (should be max one row)</returns>publicabstract IDataReader GetParentFromDb(int childTabId);///<summary>/// Gets the Tab, that hosts the given module///</summary>///<paramname="tabModuleId">TabModuleId of the module</param>///<returns>IDataReader: ParentTabId (int), ParentName (string);/// (should be max one row)</returns>publicabstract IDataReader GetTabViaTabModuleIdFromDb(
 int tabModuleId);///<summary>/// Gets node with specified TabId from Db///</summary>///<paramname="nodeTabId">TabId for node</param>///<returns>IDataReader: TabId (int), TabName (string), /// Children (int)</returns>publicabstract IDataReader GetNodeFromDb(int nodeTabId);

你可以在 SqlDataProvider.cs 文件中找到这些函数的实现。 它们基本上是简单的SQL 选择 在将来的版本中,这些语句将在存储过程中,以获得一些额外的性能。

可以在 DnnSiteMapController.cs. 中的控制器类中找到业务层函数包括:

///<summary>/// Retrieves all visible root nodes from Db///</summary>///<returns>List of root nodes as ExtendedTreeNode///</returns>public List<ExtendedTreeNode> GetRootNodesFromDb()///<summary>/// Retrieves Child Nodes from Db for given Node///</summary>///<paramname="parentNode">ParentNode, /// for which the children should be retrieved</param>///<returns>List of children as ExtendedTreeNode///</returns>public List<ExtendedTreeNode> GetChildNodesFromDb(
 TreeNode parentNode)///<summary>/// Gets the navigation path for a given Tab to the root///</summary>///<paramname="childTab">Tab for /// which the path should be retrieved</param>///<returns>List of Tabs, begining with the root /// and ending with the Child</returns>public List<Structs.Tab> GetNavigationPathFromDb(
 Structs.Tab childTab)///<summary>/// Gets the Tab, that hosts the given module///</summary>///<paramname="tabModuleId">TabModuleId of the module///</param>///<returns>Dnn TabId</returns>public Structs.Tab GetTabViaTabModuleIdFromDb(int tabModuleId)///<summary>/// Gets node with specified TabId from Db///</summary>///<paramname="nodeTabId">TabId for node</param>///<returns>Specified node; null if node is not found///</returns>public ExtendedTreeNode GetNodeFromDb(int nodeTabId)

UI代码在 ViewDnnSiteMap.ascx.cs 文件中。 将在 Page_Load 事件中应用设置,并从数据库中检索 root 节点。 然后,树扩展到当前选项卡( 承载控件的页):

protectedvoid Page_Load(System.Object sender, 
 System.EventArgs e)
{
 try {
 if (!IsPostBack)
 {
 // controller class DnnSiteMapController objDnnSiteMaps = 
 new DnnSiteMapController();
 // config settings ConfigurationSettings settings = 
 new ConfigurationSettings(this.Settings);
 // set show linesthis.TreeView1.ShowLines = settings.ShowLines;
 // set image setthis.TreeView1.ImageSet = settings.ImageSet;
 // set node wrapthis.TreeView1.NodeWrap = settings.NodeWrap;
 // set show controlsthis.pnlControls.Visible = settings.ShowControls;
 // set node indentthis.TreeView1.NodeIndent = settings.NodeIndent;
 // fill root nodes or specified rootNodethis.FillRootNodes(settings.RootNode);
 // get current TabId from DNN and expand to itthis.ExpandToTab(this.TabId);
 }
 }
 catch (Exception exc) //Module failed to load {
 Exceptions.ProcessModuleLoadException(this, exc);
 }
}

TreeNodeExpanded 事件中,我检查节点是否已经有它的子节点,如果没有,我从DB检索它们:

protectedvoid TreeView1_TreeNodeExpanded(object sender, 
 TreeNodeEventArgs e)
{
 // if node has DummyNode, else data was // already retrieved from Dbif (NodeHelper.HasDummyNode(e.Node))
 {
 // controller class DnnSiteMapController objDnnSiteMaps = 
 new DnnSiteMapController();
 // clear child nodes e.Node.ChildNodes.Clear();
 // for all child nodesforeach (ExtendedTreeNode childNode in 
 objDnnSiteMaps.GetChildNodesFromDb(e.Node))
 {
 // if root has children, add dummy nodeif (childNode.HasChildren)
 {
 NodeHelper.AddDummyNode(childNode);
 }
 // add children to expanded node e.Node.ChildNodes.Add(childNode);
 }
 }
 // select current nodethis.SelectCurrentNode();
}

iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 私有 ExpandToTab ( int tabId ) 方法在 Page_Load 事件中使用。 这里方法用于将树扩展到指定节点并选择它。 这在 Page_Load 事件中非常方便,因为你可以将选项卡设置为当前页面:

privatevoid ExpandToTab(int tabId)
{
 // controller class DnnSiteMapController objDnnSiteMaps = 
 new DnnSiteMapController();
 // collapses all nodes; IMPORTANT to use this function// instead directly TreeView.CollapseAll(), because// it can loose all nodesthis.CollapseAll();
 // find node in tree view (no roundtrip to Db) TreeNode node = 
 NodeHelper.GetNode(this.TreeView1.Nodes, tabId);
 // check if node is already in tree viewif (node!= null)
 {
 TreeNode currentNode = node;
 // expand to nodewhile (currentNode!= null)
 {
 currentNode.Expand();
 currentNode = currentNode.Parent;
 }
 }
 else// get parent path from Db {
 List<Structs.Tab> parentTabs = 
 objDnnSiteMaps.GetNavigationPathFromDb(
 new Structs.Tab(tabId, String.Empty));
 TreeNode currentNode = null;
 // expand all nodes along pathforeach (Structs.Tab nodeTab in parentTabs)
 {
 currentNode = 
 NodeHelper.GetNode(this.TreeView1.Nodes, 
 nodeTab.TabId);
 if (currentNode!= null)
 {
 currentNode.Expand();
 }
 }
 }
 // select current nodethis.SelectCurrentNode();
}

Points of interest

DNN安装说明

步骤 1: 通过DNN安装 MODULE

以主机身份登录,并在主机菜单"模块定义"中选择。 在页面的底部,按"上传新模块"键。 然后,选择. zip 文件,添加它,然后上传它。

步骤 2: 修改 Web.Config 文件( 没有这个文件,DNN将不再工作)

MODULE 在 C# 中写入,必须在 Web.Config 文件中包含以下行,在文件中 <system.web> <compilation> 节( 它应该已经存在了,但是被注释掉了):

<codeSubDirectories><adddirectoryName="DnnSiteMap"/></codeSubDirectories>
TreeNode类的值属性

因为DNN的每个标签( 页面) 都有一个 TabId,所以我将这些信息保存在每个 TreeNode 中。 为此,我使用 字段。类型为 字符串 所以我把它转换成 int 需要时。

ExtendedNode类

ExtendedNode 类直接从 System.Web.UI.WebControls.TreeNode 类派生。 它将布尔字段 HasChildren 添加到类。 当我从数据库中检索节点时,将使用这里方法,然后将该标志设置为 true ,如果它们有子节点。 通过这个小技巧,我可以为数据库提供额外的往返。

DummyNodes

如果 TreeView 控件至少有一个子节点,则该控件显示一个用于展开节点的加号。 因为我不想在扩展父节点时检索节点,所以我用 DummyNode 填充它们。 为了区别于普通节点,我将它们的value 字段设置为 -1

ConfigSettings

我封装了类 ConfigurationSettings 中的设置。 它从 Hashtable 读取设置( 比如。 ModuleSettingsBase.TabModuleSettings 或者 PortalModuleBase.Settings ),使它们类型安全,并使用默认值初始化它们。

路线图

新功能可以是:使用存储过程,定义自定义CSS类。 所以还有很多要做的。

版权

DNNSiteMap,版权( c ) 2006,BitConstruct,Halanek &控制台( BitConstruct )。

若要在取得该软件副本时免费授予任何人,如在下列条件下,必须对软件进行复制。复制。("软件")。软件。软件。subject。subject。subject。subject sublicense。

上述版权声明和本许可声明须包括在所有的副本或实质性部分的软件。

软件是"是",没有任何保证,表示或者隐含,包括但不限于销售,适合特定用途和 NONINFRINGEMENT。 作者或者版权持有人在合同。侵权或者它的他与软件或者它的他用户交易的行为。

历史记录

  • 2006/01/08 0.1
    • 概念证明,不用于高效使用( )。
  • 2006/01/13 1.0
    • 具有许多新功能( DNN 4和 ASP.NET 2.0 )的工作版本。
  • 2006/01/28 1.0.1
    • 次要 Bug 修复:现在使用 ObjectQualifier 对象的。
  • 2006/04/24 1.0.2
    • 只查看用户拥有查看权限的选项卡的新标志。
    • 高亮显示当前节点可以关闭。
  • 2006/05/07 1.0.3
    • DNNSitemap现在使用友好的url,如果在主机设置中启用。

相关文章