(c) 2002 Visual Studio Magazine
Fawcette Technical Publications

Issue: January 2002
Section: Build an XML Serialized Object
Author: Jonathan Goodyear

VB.NET	Define How to Serialize the Object
Listing A	The VSM.Application assembly contains both the serialization plumbing code and the template for the object that will be serialized. You can then tag this template with special XML serialization attributes that define how the object will be serialized.

'import relevant namespaces
Imports System
Imports System.IO
Imports System.Web
Imports System.Web.Caching
Imports System.Xml.Serialization

Namespace VSM.Application
	Public Class AppConfiguration
		Public Shared ReadOnly _
			Property Settings() As _
			AppConfigurationData
			Get
				'get a reference to the current http 
				'request's context
				Dim context As HttpContext = _
					HttpContext.Current

				'attempt to load the configuration 
				'settings from cache
				Dim data As AppConfigurationData = _
					CType(context.Cache _
					("AppConfigurationData"), _
					AppConfigurationData)
				
				If data Is Nothing Then
					'get the path of the 
					'configuration file
					Dim configPathFile As String = _
						context.Server.MapPath _
						("AppConfigurationData. _
						config")

					'the configuration settings are 
					'not in cache, or have been 
					'invalidated, so get a fresh copy
					data = LoadSettings _
						(configPathFile)

					'store the configuration settings 
					'in cache, so we'll have a copy 
					'when we need it again
					context.Cache.Insert _
						("AppConfiguration", data, _
						New CacheDependency _
						(configPathFile))
				End If

				Return data
			End Get
		End Property

		Private Shared Function LoadSettings _
			(fileName As String) As _
			AppConfigurationData
			'read our configuration data file into 
			'a stream
			Dim reader As StreamReader = _
				File.OpenText(fileName)

			'create an XMLSerializer object that 
			'can deserialize our configuration data
			Dim serializer As XmlSerializer = New _
				XmlSerializer(GetType _
				(AppConfigurationData))

			'deserialize our configuration data and 
			'cast it to the AppConfigurationData 
			'datatype
			Dim data As AppConfigurationData = _
				CType(serializer.Deserialize _
				(reader),AppConfigurationData)

			'close the stream
			reader.Close()

			Return data
		End Function

		Public Shared Sub SaveSettings(data As _
			AppConfigurationData)
			'get a reference to the current 
			'request's http context
			Dim context As HttpContext = _
				HttpContext.Current

			'get the path of the configuration file
			Dim configPathFile As String = _
				context.Server.MapPath _
				("AppConfigurationData.config")

			'open the configuration file
			Dim writer As StreamWriter = _
				File.CreateText(configPathFile)
			Dim serializer As New XmlSerializer _
				(GetType(AppConfigurationData))

			'serialize the current state of the 
			'configuration object to the 
			'configuration file
			serializer.Serialize(writer, data)

			'close the stream
			writer.Close()
		End Sub
	End Class

	Public Class AppConfigurationData
		'declare private fields
		Private _connectString As String
		Private _adminPassword As String
		Private _cacheIncrements() As _
			CacheIncrement

		<XmlElement> _
		Public Property ConnectString() As String
			Get
				Return _connectString
			End Get
			Set
				_connectString = Value
			End Set
		End Property

		<XmlElement()> _
		Public Property AdminPassword() As String
			Get
				Return _adminPassword
			End Get
			Set
				_adminPassword = Value
			End Set
		End Property

		<XmlArray> _
		Overloads Public Property _
			CacheIncrements() As CacheIncrement()
			Get
				Return _cacheIncrements
			End Get
			Set
				_cacheIncrements = Value
			End Set
		End Property

		<XmlIgnore> _
		Overloads ReadOnly Property _
			CacheIncrements(key As String) As _
			CacheIncrement
		Get
			Dim increment As CacheIncrement

			For Each increment In _cacheIncrements
				If key = increment.Key Then
					Return increment
				End If
			Next increment

			Return Nothing
			End Get
		End Property
	End Class

	Public Class CacheIncrement
		'declare private fields
		Private _key As String
		Private _seconds As Integer

		'declare public property interface 
		'procedures
		<XmlAttribute> _
			Public Property Key As String
			Get
				Return _key
			End Get
			Set
				_key = Value
			End Set
		End Property

		<XmlAttribute> _
			Public Property Seconds As Integer
			Get
				Return _seconds
			End Get
			Set
				_seconds = Value
			End Set
		End Property
	End Class
End Namespace

XML	Deserialize Persisted XML Data
Listing B	The AppConfigurationData.config file contains the persisted XML data for the AppConfigurationData object. Deserialize this data through a call to the shared Settings property of the AppConfiguration class.

<?xml version="1.0" encoding="utf-8"?>
<AppConfigurationData xmlns:xsi=
	"http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<ConnectString>Password=;User ID=sa;Initial 
		Catalog=pubs;Data Source=localhost
		</ConnectString>
	<AdminPassword>vsmrox</AdminPassword>
	<CacheIncrements>
		<CacheIncrement Seconds="3600" Key="lnav" 
			/>
		<CacheIncrement Seconds="1800" Key="body" 
			/>
		<CacheIncrement Seconds="3600" Key="rnav" 
			/>
	</CacheIncrements>
</AppConfigurationData>


ASP.NET, VB.NET	Read and Write to the Persisted Data
Listing 1	You can use a simple Web form interface to read and write to the persisted XML configuration data. The AppConfiguration object acts as a broker to persist and de-persist the AppConfigurationData settings object.

<%@ Page Language="VB" %>
<%@ Import Namespace="VSM.Application" %>

<script language="VB" runat="server">
Protected Sub Page_Load(sender As Object, e As _
	System.EventArgs)
	If Not IsPostBack Then
		LoadConfigurationForm()
	End If
End Sub

Private Sub LoadConfigurationForm()
	'create a configuration object instance
	Dim settings As AppConfigurationData = _
		AppConfiguration.Settings

	'set the web form values based on the 
	'properties
	'of the configuration object
	ConnectString.Text = settings.ConnectString
	AdminPassword.Text = settings.AdminPassword
	LNavCacheSeconds.Text = _
		settings.CacheIncrements _
		("lnav").Seconds.ToString()
	BodyCacheSeconds.Text = _
		settings.CacheIncrements _
		("body").Seconds.ToString()
	RNavCacheSeconds.Text = _
		settings.CacheIncrements _
		("rnav").Seconds.ToString()
End Sub

Protected Sub SaveConfiguration_Click(sender As _
	Object, e As System.EventArgs)
	'create a configuration object instance
	Dim settings As AppConfigurationData = _
		AppConfiguration.Settings

	'set the configuration object properties to 
	'the new settings that we specified in the web 
	'form
	settings.ConnectString = ConnectString.Text
	settings.AdminPassword = AdminPassword.Text
	settings.CacheIncrements("lnav").Seconds = _
		Convert.ToInt32(LNavCacheSeconds.Text)
	settings.CacheIncrements("body").Seconds = _
		Convert.ToInt32(BodyCacheSeconds.Text)
	settings.CacheIncrements("rnav").Seconds = _
		Convert.ToInt32(RNavCacheSeconds.Text)

	'persist the new settings to disk
	AppConfiguration.SaveSettings(settings)
End Sub
</script>

<html>
<head>
<title>Serialized Application 
	Configuration</title>
</head>
<body>
<form runat="server">
<b>Configuration Settings:</b><br />
Connect String:
<asp:TextBox id="ConnectString" Columns="75" 
	runat="server" /><br />
Admin Password:
<asp:TextBox id="AdminPassword" runat="server" 
	/><br />
LNav Cache Seconds:
<asp:TextBox id="LNavCacheSeconds" runat="server" 
	/><br />
Body Cache Seconds:
<asp:TextBox id="BodyCacheSeconds" runat="server" 
	/><br />
RNav Cache Seconds
<asp:TextBox id="RNavCacheSeconds" runat="server" 
	/><br />
<asp:Button id="SaveConfiguration"
	text="Save Configuration"
	onclick="SaveConfiguration_Click"
	runat="server" />
</form>
</body>
</html>
