Wednesday, December 26, 2007

Reading ASP.NET Application Settings From Web.config Using Classic ASP

ASP 101 - Reading ASP.NET Application Settings From Web.config Using Classic ASP

Whether you're trying to share settings between your ASP.NET and legacy
classic ASP apps or are simply looking for a way to make your eventual migration
to ASP.NET easier, this piece of code might be just the ticket.


The code came about because I recently found myself tasked with the annoying
job of migrating a database server from an old machine to a newer piece of
hardware. The database server was acting as the backend data store for a web
site that's been around for quite a few years and was running a mix of classic
ASP and ASP.NET applications.


Thankfully both the classic ASP and ASP.NET applications were relatively
careful about keeping their connection strings centralized, but I was still
needed to change the setting in both the ASP and ASP.NET applications. The
switch ended up going quite smoothly, but as I was looking around to make sure
I'd found everything, I started to realize just how many settings and how much
information was duplicated between the legacy and new applications. It seemed
like there had to be a better way.


Since pretty much all new development is being done on .NET, the obvious
solution was to find an easy way for classic ASP applications to be able to read
their settings from the same source as the ASP.NET applications: the
web.config file.




The Code



As we're all aware, the data in the web.config file is stored in
an XML-based format. Now I'll admit that my XML skills probably aren't up to par
with those of you who use it on a regular basis, but I did manage to hack
together a couple short functions to facilitate reading connection strings and
application settings from the site's root web.config file.








readsettings.asp

<%@ Language="VBScript" %>
<%
Option Explicit

Function GetAppSetting(strAppSettingKey)
Dim xmlWebConfig
Dim nodeAppSettings
Dim nodeChildNode
Dim strAppSettingValue

Set xmlWebConfig = Server.CreateObject("Msxml2.DOMDocument.6.0")
xmlWebConfig.async = False
xmlWebConfig.Load(Server.MapPath("/Web.config"))

If xmlWebConfig.parseError.errorCode = 0 Then
Set nodeAppSettings = xmlWebConfig.selectSingleNode("//configuration/appSettings")
For Each nodeChildNode In nodeAppSettings.childNodes
If nodeChildNode.getAttribute("key") = strAppSettingKey Then
strAppSettingValue = nodeChildNode.getAttribute("value")
Exit For
End If
Next
Set nodeAppSettings = Nothing
End If
Set xmlWebConfig = Nothing

GetAppSetting = strAppSettingValue
End Function

Function GetConnectionString(strConnStringName)
Dim xmlWebConfig
Dim nodeConnStrings
Dim nodeChildNode
Dim strConnStringValue

Set xmlWebConfig = Server.CreateObject(&quot;Msxml2.DOMDocument.6.0")
xmlWebConfig.async = False
xmlWebConfig.Load(Server.MapPath("/Web.config"))

If xmlWebConfig.parseError.errorCode = 0 Then
Set nodeConnStrings = xmlWebConfig.selectSingleNode("//configuration/connectionStrings")
For Each nodeChildNode In nodeConnStrings.childNodes
If nodeChildNode.getAttribute("name") = strConnStringName Then
strConnStringValue = nodeChildNode.getAttribute("connectionString")
Exit For
End If
Next
Set nodeConnStrings = Nothing
End If
Set xmlWebConfig = Nothing

GetConnectionString = strConnStringValue
End Function
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Reading ASP.NET Application Settings From Web.config Using Classic ASP</title>
</head>
<body>

<p>
The following values are all read from the <code>web.config</code>
file located in the root of the web site.
</p>

<p>
Welcome Message: <%= GetAppSetting("WelcomeMessage") %>
</p>

<p>
Sample Connection String: <%= GetConnectionString("SampleConnString") %>
</p>

<p>
Thank You Message: <%= GetAppSetting("ThankYouMessage") %>
</p>

</body>
</html>

As you can see they're quite easy to use both functions are quite similar.
The only real difference between the two are related to the location of the
settings in the XML tree and the syntax differences between the application
settings and connection strings sections.


Speaking of the settings, if you use the functions as written, you'll be
retrieving settings by using the connection string's name or the key associated
with an application setting. These values are case sensitive, so if you're
having trouble, make sure you've got everything spelled exactly the same... case
and all.


Although you'll most likely be using your own existing
web.config file, I'm including a simple one here for illustration.






web.config

<?xml version="1.0"?>
<!--
Comments and whitespace shouldn't cause any problems.
-->
<configuration>
<appSettings>
<add key="WelcomeMessage" value="Welcome to our site." />
<add key="ThankYouMessage" value="Thanks for visiting... please come back soon." />
</appSettings>
<connectionStrings>
<add name="SampleConnString"
providerName="System.Data.OleDbClient"
connectionString="Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=C:\Inetpub\wwwroot\App_Data\test.mdb;"
/>
</connectionStrings>
<system.web>
<compilation debug="false" />
</system.web>
</configuration>


That's all there is to it. A quick and easy way for you to enable your
classic ASP applications to read application settings and connection strings
from ASP.NET's web.config file.


Caching


I probably didn't need to make this a separate heading, but I didn't want
people to skip right over it. I just want to warn you that I have not
performance tested these functions. While they seem to execute extremely
quickly, they are hitting the file system each time you use them. For busy sites
and/or frequently used values, you really should consider caching the values to
memory.