Create CSS Links in DotNetNuke.

I wanted to have another page (not default.aspx) in DotNetNuke based application. I found that there is no common code to generate CSS links. Actually, core code to create CSS links is duplicated in a few places. I’ve created a common class, that can be used in my custom page, as well as  from Default.aspx and ComponentsSkinsSkin.vb . The class is posted in comment to the isssue. 

Using Configuration.Section to access subsection

I have a section in Web.Config:


  <applicationSettings>


    <FSBsnsCsLib.Properties.Settings>



   </</FSBsnsCsLib.Properties.Settings>


 </</applicationSettings>


I’ve tried to access inner section using shortcut “Section/Subsection“


string sSectionName=”applicationSettings/FSBusinessLib.My.MySettings”;
System.Configuration.ClientSettingsSection sectSettings = (ClientSettingsSection)config.Sections[sSectionName];


but it returned null.


The correct way is the following:


const string cnstApplicationSection = applicationSettings;
ConfigurationSectionGroup grpApplicationSection = config.SectionGroups[cnstApplicationSection];
string sSectionName=”FSBusinessLib.My.MySettings”;
System.Configuration.ClientSettingsSection sectSettings = grpApplicationSection .Sections[sSectionName];

This approach is used in my ConfigurationHelper class

Update Dynamic Web reference URLs During Installation in Visual Studio 2005

I am using dynamic URLBehavior for some web services and during Setup changing web services URLs to appropriate value according to approach described in  article “Walkthrough: Redirecting an Application to Target a Different XML Web Service During Installation “. 
As I already posted, Visual Studio 2005 changed the way where URLs are stored and now saves it inside section of config file. The differences between different types of projects are detailed described in post “How to share dynamic URLs across multiple Web Application Projects” .

I’ve created a class ConfigurationHelper, that helps to update the Dynamic URLs for Web Services.
I’ve tried to utilize ApplicationSettingsBase Class with SettingsProvider derived class to be called from Installer, but didn’t succesded.
It wasn’t too hard to implement it using  System.Configuration.Configuration/ClientSettingsSection and related classes.
One not obvious trick: when you assign value to the existing section element , it is required manually sectSettings.SectionInformation.ForceSave = true.

 Example of use the class:

 

String VDir = Context.Parameters[“VDir”]; //’TARGETVDIR
String Port = Context.Parameters[“Port”]; //’TARGETPORT
String Site = Context.Parameters[“TARGETSITE”]; //http://jrbii.spaces.live.com/blog/cns!5E74A5E75ECFD62E!183.entry
System.Configuration.Configuration config = ConfigurationHelper.OpenWebConfiguration(Site, VDir);
ConfigurationHelper.WriteDynamicUrl(config, “FSBusinessLib.My.MySettings”, “FSBusinessLib_CommonWS_CommonServices”, ServerName, VirtualDirectory, “CommonServices.asmx”);
config.Save(ConfigurationSaveMode.Full);

//The class code is below:

namespace FSCSharpLib

{

    using Microsoft.VisualBasic;

    using Microsoft.VisualBasic.CompilerServices;

    using System;

    using System.Collections;

    using System.Diagnostics;

    using System.IO;

    using System.Reflection;

    using System.Windows.Forms;

    using System.Xml;

    using System.Web.Configuration;

    using System.Configuration;

    using FSHelperLib;

    //TODO Use Configuration/ConfigurationManager where appropriate

    //TODO merge with  AppSettingsHelper.cs

    public static class ConfigurationHelper

    {

        public static System.Configuration.Configuration OpenWebConfiguration(string VDir,string Site )

        {

        //’from http://72.14.203.104/search?q=cache:qQsdbMB2mf8J:winfx.msdn.microsoft.com/library/en-us/dv_aspnetconfig/html/cce0dd24-5e96-41b8-96bb-6a8af7bcdb14.asp++OpenWebConfiguration+IIS+site+&hl=en&gl=au&ct=clnk&cd=19

        //’For example, if the IIS metabase path is W3SVC/1/Root/TraceDemo, then the path is “1/TraceDemo”??

 

            string SiteNumber = Site.Remove(0, Site.LastIndexOf(“/”) + 1);//retrieve “1” from @”/LM/W3SVC/1″;

            string RootVDir = “/” + VDir;//'”/vKnowledge”   

            Trace.WriteLine(“RootVDir “ + RootVDir + ” SiteNumber “ + SiteNumber);

            System.Configuration.Configuration configuration1 = WebConfigurationManager.OpenWebConfiguration(RootVDir, SiteNumber);

            return configuration1;

        }

        ///

        /// from http://weblogs.asp.net/bradleyb/archive/2006/05/04/445133.aspx  not applicable for VS03 and in VS05 Web Site projects

        ///“applicationSettings” in VS05 WinForm projects and ClassLibrary projects

        ///

        ///

        ///
e.g “applicationSettings/FSBusinessLib.My.MySettings” or just “FSBusinessLib.My.MySettings”

        ///for CS FSBsnsCsLib.Properties.Settings http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=57690&SiteID=1

        ///for vb FSBusinessLib.My.MySettings

        ///

        ///

        public static System.Configuration.ClientSettingsSection FindOrCreateSettingsSection(Configuration config, string SectionName)

        {

            const string cnstApplicationSection = “applicationSettings”;

            string sSectionName = StringHelper.RightAfterLast(SectionName, “/”);//remove “applicationSettings/” prefix if applicable ,

            //if(sSectionName.IndexOf(‘/’)<0)

            //{

            //    sSectionName = cnstApplicationSection + ‘/’ + SectionName;

            //}

            ConfigurationSectionGroup grpApplicationSection = config.SectionGroups[cnstApplicationSection];

            if (grpApplicationSection == null)

            {

                grpApplicationSection = new ApplicationSettingsGroup();

                config.SectionGroups.Add(cnstApplicationSection, grpApplicationSection);

            }

            System.Configuration.ClientSettingsSection sectSettings = (ClientSettingsSection)grpApplicationSection.Sections[sSectionName];

            if (sectSettings == null)

            {

                sectSettings = new ClientSettingsSection();

                grpApplicationSection.Sections.Add(sSectionName, sectSettings);

                sectSettings.SectionInformation.ForceSave = true;

                config.Save(ConfigurationSaveMode.Full);

                Debug.WriteLine(“Section name: {0} created”,     sectSettings.SectionInformation.Name);

            }

           

        }

        public static System.Configuration.ClientSettingsSection WriteSettingsValue(ClientSettingsSection sectSettings, string Key,string value)

        {

            SettingElement elem = sectSettings.Settings.Get(Key);

            if (elem == null)

            {

                elem = new SettingElement(Key,SettingsSerializeAs.String );

                XmlDocument doc= new XmlDocument();

                XmlElement xmlValue = doc.CreateElement(“value”);

                xmlValue.InnerText = value;

                SettingValueElement valueElem= new SettingValueElement();

                valueElem.ValueXml = xmlValue;

                elem.Value = valueElem;

                sectSettings.Settings.Add(elem);

            }

            else

            {

                elem.Value.ValueXml.InnerText = value;

                sectSettings.SectionInformation.ForceSave = true; //important, changing Value.ValueXml value is not enough

            }

 

        }

        //don’t forget to call config.Save after finish all writes

        public static void WriteDynamicUrl(Configuration config,

          string SettingsGroupName, string SettingName, string ServerName,string VirtualPath,string ServiceFile)

        {

            System.Configuration.ClientSettingsSection sectSettings  = ConfigurationHelper.FindOrCreateSettingsSection(config, SettingsGroupName);

            String sValue = HttpRequestHelper.HttpURL(ServerName, VirtualPath, ServiceFile);

            ConfigurationHelper.WriteSettingsValue(sectSettings, SettingName, sValue);

        }

 

    }//end of class

}//end of namespace

 


Use VS 2005 Web Deployment Project with DotNetNuke

Some time ago I blogged that my attempt to use VS 2005 Web Deployment Project  failed with not very helpful Aspnet_merge.exe Exited With Code 1 message.  As it is described in the thread, the actual error reported was
An error occurred when merging assemblies: ILMerge.Merge: ERROR!!: Duplicate type ‘DotNetNuke.UI.Skins.Controls.SolPartMenu’ found in assembly ‘App_Web_k5hhsnh0’.


I found that there are 2 files “adminSkinssolpartmenu.ascx“ and “adminSkinsmenu.ascx“ referring to the  same SolPartMenu.ascx.vb. 2 files generated partial classes with the same name and caused “Duplicate type” error during merge.


I didn’t find where “adminSkinsmenu.ascx“ is used, so I just excluded it from the project.


The recomendation how to fix the problem in general are described in MS article “Common Web Project Conversion Issues and Solutions”, issue 26.


After this I’ve got the next error “Duplicate type ‘DotNetNuke.UI.WebControls.SolPartActions’” , that I fixed by excluding adminContainersactions.ascx from the project.


After this I was able to build Deployment project without any errors, that gave me one DLL per subfolder. 


The problem is reported to DNN Support.