DNN ability to ‘Publish Web Site’

3 years ago I’ve posted a workaround regarding DNN

BUG App_GlobalResources and ‘Publish Web Site’ in VS2005 
The issue is still not resolved and I recently received an email

I would like to thank you a lot for your post on a DNN forum which explain how to use DNN in precompiled mode.

( AppGlobalRessources…… )

T H A N K S !!!!!!!!!!

 I am glad that the workaround is still useful, but DNN team should create a new version(even with breaking changes)

Do not pass data between static methods using static data members.

In one of static class in our application, I found local static members that were used to pass data between calls of static methods.
It’s wrong and can cause errors that are intermittent and very hard to reproduce.
The problem will happen if the same code executed for 2 users simultaneously. In this case value for one user could be used for the second user and result will be unpredictable.
The code was similar the following:
    public static class HelperClass
       private static string _dataToPass = “”;
   static void Method1(string param)
_dataToPass =param;
   static void Method2()
//logic based on _dataToPass value;
The pattern is popular for instance object, when one method saves state in the instance, and other method use it, but it is not acceptable for static class.
Consider to use singleton pattern, if you have shared for the domain object.
The issue is well known(e.g. see Statics & Thread Safety: Part I   and Part 2 ), but I decided to write about it again.

Helper String function to TrimLength

            /// <summary>
            /// If lenght of the string is greater than max allowed, remove the end
            /// </summary>
            /// <param name=”str”></param>
            /// <param name=”maxLength”></param>
            /// <returns></returns>
            public static string TrimLength(string str, int maxLength)
                if (str.Length > maxLength)
                    str = str.Remove(maxLength);
                return str;

Possible errors when using Web Setup project to upgrade version, that was XCopied

I am using Web Setup project to install Web Site Project(customized version of DotNetNuke). It installs a lot of DLL with meaningless names(like App_Web_42q_drww.dll) into BIN directory.
If user upgrades later to the new version of the project MSI installer seems smart enough to delete old DLLs and install another set of DLLs with different unfriendly names.

The problem happens if site to upgrade wasn’t installed using Web Setup MSI, but was XCopied.The sample scenario is the following:
An administrator  installed web Application into virtual directory MyWebApp1. Then the administrator  made a copy of application MyWebApp1Copy.
On teh time of upgrade he/she decided to apply upgrade directly to MyWebApp1Copy virtual directory. In this case old set of DLLs in BIN is not deleted, but both old and new co-exist. It causes different errors like

Compiler Error Message: BC30456: ‘InitializeCulture’ is not a member of ‘ASP.default_aspx’.

The simplest way to workaround the mess is to rename the web apllication folder and install your application as new.

Related thread : BC30456: ‘InitializeCulture’ is not a member of…

DotNetnuke 4.4 RewriterUtils.RewriteUrl breaking change in adding QueryString.

I am using modified version of DNN HttpModulesUrlRewriteUrlRewriteModule,
in particular I am calling their
Friend RewriterUtils.RewriteUrl function. In 4.0.3 version it expected URL parameter without QueryString and added queryString from context.Request.QueryString inside the function.
But in 4.4. my code stopped working.
The reason was that they removed the code to add querystring information from the function and made it  responsibility of a caller.
It certainly makes sense, but it will be easier for me(and other developers), if comments with description how function works and what the changes are done will be added to the source code.
It is the expected code style for open source project.

DotNetNuke changes in Web.Config from 4.0.3 to 4.4

I moved from DNN 4.0.3 to DNN 4.4 and noticed that there are significant web.config changes (actually as a part of 4.3 Membership Services Provider Abstraction ).

However I didn’t find any clear documentation about Web.Config changes.
From my understanding the folowing changes happened:
1. Microsoft ASP.NET  membership  defaultProvider changed from “DNNSQLMembershipProvider” to standard MS AspNetSqlMembershipProvider –System.Web.Security.SqlMembershipProvider.
2.roleManager and profile providers sections were deleted from system.web section of web.config.
3. New sections members“,roles“,profiles” were added to  dotnetnuke sectionGroup


DotNetNuke.Services.Upgrade.ExecuteScripts method

DotNetNuke function Upgrade.ExecuteScripts(ByVal strProviderPath As String)
actually doesn’t use strProviderPath, but always uses ApplicationMapPath & “InstallScripts” folder.

It reads all files in the folder and deletes them after execution.

It is also triggered only by InstallDNN.
The behavior is different to installmodules folder, where modules are installed also during UpgradeDNN.

The issue reported  here(in comments).

I’ve also asked a question in DNN Forums “Is “installscripts” folder obsolete?


StyleSheetsManage class for DotNetNuke

I found that code to create CSS links is duplicated in a few places. I’ve created a common class, that can be used from Default.aspx,ComponentsSkinsSkin.vb and third-party modules if required.

Originally I’ve posted it to DNN support , but it is not searchable by Google. So I desided to post it here as well.

 The code is the following:

Imports System.Diagnostics

Imports System.IO

Imports Microsoft.VisualBasic

Imports DotNetNuke

Imports DotNetNuke.Framework


Public Class StyleSheetsManage

    ‘Based on C:ProjectsFuncSolnFSDNNDefault.aspx.vb ManageStyleSheets

    Public Shared Sub AddStyleSheetFile(ByVal objCSS As Control, ByVal sFileName As String)

        ‘ initialize reference paths to load the cascading style sheets

        ‘Dim objCSS As Control = Me.FindControl(“CSS”)

        Dim ID As String

        Dim PortalSettings As PortalSettings = PortalController.GetCurrentPortalSettings

        Dim sHref As String = “”

        Dim objCSSCache As Hashtable = CType(DataCache.GetCache(“CSS”), Hashtable)

        If objCSSCache Is Nothing Then

            objCSSCache = New Hashtable

        End If

        If Not objCSS Is Nothing Then

            Select Case (sFileName.ToLower())

                Case “default.css”

                    AddStyleSheetLink(objCSS, Common.Globals.HostPath, sFileName)

                Case “skin.css”

                    ‘ skin package style sheet

                    sHref = AddToCacheIfRequired(objCSSCache, PortalSettings.ActiveTab.SkinPath, “skin.css”)

                    If sHref <> “” Then

                        AddStyleSheetLink(objCSS, PortalSettings.ActiveTab.SkinPath, sFileName)

                    End If

                Case “skinsrc”

                    ‘ skin file style sheet

                    ID = CreateValidID(Replace(PortalSettings.ActiveTab.SkinSrc, “.ascx”, “.css”))

                    sHref = AddToCacheIfRequired(objCSSCache, ID, “”)

                    If sHref <> “” Then

                        AddStyleSheetLink(objCSS, ID, “”)

                    End If

                Case “portal.css”

                    AddStyleSheetLink(objCSS, PortalSettings.HomeDirectory, “portal.css”)

                Case Else


            End Select

        End If

    End Sub

    Public Shared Function AddStyleSheetLink(ByVal objCSS As Control, ByVal sPath As String, ByVal sFileName As String) As String

        Dim sHref As String = “”

        If Not objCSS Is Nothing Then

            Dim objLink As HtmlGenericControl = New HtmlGenericControl(“LINK”)

            Dim ID As String = CreateValidID(sPath)

            objLink.ID = ID

            objLink.Attributes(“rel”) = “stylesheet”

            objLink.Attributes(“type”) = “text/css”

            sHref = sPath & sFileName

            objLink.Attributes(“href”) = sHref


        End If

        Return sHref

    End Function

    Public Shared Function AddToCacheIfRequired(ByVal objCSSCache As Hashtable, ByVal sPath As String, ByVal sFileName As String)

        Dim PortalSettings As PortalSettings = PortalController.GetCurrentPortalSettings

        Dim sHref As String = “”

        Dim ID As String = CreateValidID(sPath)

        If objCSSCache.ContainsKey(ID) = False Then

            If File.Exists(HttpContext.Current.Server.MapPath(sPath) & sFileName) Then

                sHref = sPath & sFileName

            End If

            objCSSCache(ID) = sHref

            If Not Common.Globals.PerformanceSetting = Common.Globals.PerformanceSettings.NoCaching Then

                DataCache.SetCache(“CSS”, objCSSCache)

            End If


            sHref = objCSSCache(ID)

        End If

        Return sHref

    End Function

End Class

DotNetNuke function FindControlRecursive -not clear name.

DotNetNuke has function FindControlRecursive. Initially I assumed that it search down hierarchy, but it doesn’t work as I expected.
After reading code it seems that it searched siblings or parens siblings up to the top of hierarchy.
So the name is misleading.

Fortunately  there is a separate function FindControlRecursiveDown, that does what I needed.

Using Web Application Project(WAP) for development of DotNetNuke modules with Edit and Continue Support

I am using Web Application Project(WAP) for development of DotNetNuke modules.

The general approach is discussed in DNN forum thread here.


My VS solution consists of main WAP Project and one or more User Control Libraries similar to described in Tutorial 6: Creating and Using User Control Libraries.

The main WAP Project basically includes one DNNDebug.aspx  file (as well as web.config and global.asax),  that allows me to load and test my user controls.

The User Control Libraries(DNN modules) are physically located in DesktopModules subfolder of the main project, so I  don’t need to copy ascx files from control library to main project subfolders as it is recommended in  the Tutorial.


Main WAP project has references to module projects, which ensures that module DLLs are copied to main project bin folder by VS.


The using simple main WAP project has an advantage compare to Vladan’s BlankModule approach http://vladan.strigo.net/Default.aspx?tabid=78The solution can use Development Web Server and “Edit and Continue” will work!


When I am satisfied with testing and debugging of a new module with DNNDebug.aspx, the next step is to copy the module to normal DNN Web Site Project. It is required to copy module DLL to bin directory and ASCX files to WSP DesktopModules subfolder. I also need to remove CodeBehind attribute From Ascx files, because I do not want copy source code ascx.vb files to the WSP project. The procedure how to set the project to do it automatically described in the thread “How to use WAP User Control Libraries from Web Site Project and my blog  article “Utility to Remove CodeBehind attribute From Ascx files .