As long-time DotNetNuke users well know, DotNetNuke contains an extensive API that makes the platform extremely powerful and flexible. Over time the core APIs have continued to expand as new features were added and existing features were enhanced. One of the core APIs which has been part of DotNetNuke since 4.6 was released three years ago today is the XML Merge API.
The XML Merge API was developed to enable developers to define changes that need to occur to any xml based file within the website. It is primarily used by the core framework to make updates to web.config but has utility beyond just updating web.config. Web.config management was a huge problem in early versions of DotNetNuke. Managing and applying the web.config changes every time you upgraded DotNetNuke was a time-consuming and error-prone process. The XML Merge API was developed in part to address this need.
When I first created the API, I needed a way to merge dozens of custom URL rewriter rules into the siteurls.config for the AspDotNetStorefront module. These rules could change with new versions of the ASPDNSF module and so I also needed to support the ability to apply these changes in a version specific manner. My first version was included as part of the ASPDNSF module, but due to a contractual arrangement, I was able to make this API available in DotNetNuke as well.
Since the very beginning, DotNetNuke has supported the ability to apply versioned SQL scripts to the database. The XML Merge API extended this concept to the system configuration files. Similar to the XX.XX.XX.SqlDataProvider files, the core uses a series of XX.XX.XX.config files in the Install/Config folder within the DotNetNuke website. Each merge script defines an atomic set of changes that will occur for upgrades to a specific DotNetNuke version. As the upgrade process steps through each version in the upgrade chain, it applies the associated sqldataprovider scripts as well as the associated config merge scripts.
One extremely useful core script is the Net35.config script which makes the necessary changes to the web.config file to upgrade a site from ASP.Net 2.0 to ASP.Net 3.5. If you look at the Net35 merge script, you will find that there are a couple dozen changes that are needed to web.config to make the transition from 2.0 to 3.5. I have had to add these changes manually to a user’s site on more than one occasion and it is not a fun task.
Unfortunately we are finding situations where the merge scripts may not actually execute properly. If the administrator has locked down changes to web.config or if they have added changes to web.config which fundamentally changes the XML structure, then it is possible that the scripts won’t be executed. In those situations the user is not left with any option beyond hand editing, which as I previously pointed out is a very tedious process for any significant change.
One useful feature that exists in DotNetNuke is the ability to manually execute SQLDataProvider scripts using the Host/SQL page. This module allows you to load an existing SQL script, edit the script and apply it to your database. If a SQLDataProvider script doesn’t work during an upgrade you have the option to easily apply this script manually to your site. If you need to test SQL scripts for your modules during development to make sure they will work properly, you can use the SQL page to handle that task as well.
I thought it would be great if we had a page that performed a similar function for XML Merge scripts. Not being one to wait for others to create the feature I coded one up for myself. I wanted the new module to have all of the same basic features as the SQL module and the result is pretty close. The UI can use a little tweaking, but all of the needed functionality is present.
The module was actually pretty easy to implement since it is really just calling the core framework. A simple event handler to take care uploading the file:
Protected Sub cmdUpload_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdUpload.Click
If IsValidDocType(uplMergeScript.PostedFile.ContentType) Then
Dim scriptFile As New System.IO.StreamReader(uplMergeScript.PostedFile.InputStream)
txtMerge.Text = scriptFile.ReadToEnd
and a simple event handler to execute the script when the “Execute Merge” link button is pressed:
Protected Sub cmdExecute_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdExecute.Click
If IsValidXmlMergDocument(txtMerge.Text) Then
Dim doc As New System.Xml.XmlDocument()
Dim merge As New DotNetNuke.Services.Installer.XmlMerge(doc, "", "")
Catch ex As Exception
Skins.Skin.AddModuleMessage(Me, Localization.GetString("ERROR_Merge", Me.LocalResourceFile), ModuleMessage.ModuleMessageType.RedError)
That’s really all there is to it. I have packaged up the module and added it to the DotNetNuke forge. I hope to get it incorporated into the upcoming DotNetNuke 5.6 release which should be out later this fall, but in the meantime feel free to download the module and use it on your own sites.