DotNetNuke: Sub-Pages get lost when moving parent page with drag-and-drop

These days I found a (in my opinion very critical) bug in the DotNetNuke’s core module “Pages” when using the drag-and-drop functionality to rearrange the page structure. In detail, when moving a page that has sub-pages to a new parent page all sub-pages get lost.

You can try out this problem in a fresh DotNetNuke 7.1.2 environment by moving the page “About Us” (with its sub-page “StyleGuide”) under the page “Contact Us”. After reloading the website, the page “About Us” was moved to the new parent page as expected, but you won’t find the sub-page “StyleGuide” any longer.

After some research, I found out that the records in the table [Tabs] are not updated properly. After moving the “About Us” page the data looks as follows:

SELECT [TabID] ,[PortalID] ,[TabName] ,[ParentId] ,[Level] ,[TabPath]
FROM [dbo].[Tabs]
WHERE [TabName] = 'About Us' OR [TabName] = 'StyleGuide' OR [TabName] = 'Contact Us'

TabID	PortalID	TabName		ParentId	Level	TabPath
58	0		About Us	60		1	//ContactUs//AboutUs
60	0		Contact Us	NULL		0	//ContactUs
61	0		StyleGuide	58		1	//AboutUs//StyleGuide

As you can see the columns [Level] and [TabPath] of the page “StyleGuide” contain wrong data ([Level] should be 2 instead of 1 and [TabPath] should be ‘//ContactUs//AboutUs//StyleGuide’ instead of ‘//AboutUs//StyleGuide’). After correcting the data, the sub-page is included in the menu again.

Since DotNetNuke uses some C# logic that removes white-spaces and other special characters from the [TabName] to get data for the [TabPath], I did not find any way to fix the data automatically using a SQL update script and ended up in manually fixing the data.

You can use the following SQL statement to find incorrect records in your [Tabs] table:

SELECT [TabID], [TabName], [Level] as ActualLevel, [TabPath] as ActualTabPath,
(SELECT [Level] FROM [dbo].[Tabs] AS parent WHERE parent.[TabId] = child.[ParentId]) as ParentLevel,
(SELECT [TabPath] FROM [dbo].[Tabs] AS parent WHERE parent.[TabId] = child.[ParentId]) as ParentTabPath
FROM [dbo].[Tabs] AS child
WHERE [Level] != (SELECT [Level] FROM [dbo].[Tabs] AS parent WHERE parent.[TabId] = child.[ParentId]) + 1
OR CharIndex((SELECT [TabPath] FROM [dbo].[Tabs] AS parent WHERE parent.[TabId] = child.[ParentId]), [TabPath]) = 0

After moving the “About Us” in the DNN 7.1.2 environment as explained above, the statement returns the following result:

TabID	TabName		ActualLevel	ActualTabPath		ParentLevel	ParentTabPath
61	StyleGuide	1		//AboutUs//StyleGuide	1		//ContactUs//AboutUs

I’ve created a bug report and hopefully this bug gets fixed in the next version.

Leave a Reply

Your email address will not be published. Required fields are marked *