©2006 Alex Homer – alex@stonebroom.com
This series of articles looks at the patterns & practices Enterprise Library tools, and how you can use them in your ASP.NET applications. The five articles are:
· Part 1 - An Introduction to Enterprise Library
· Part 2 - Working with Enterprise Library in ASP.NET
· Part 3 - Using Enterprise Library in ASP.NET Partial Trust Mode
· Part 4 - Extending Enterprise Library with Custom Providers
· Part 5 - Adding Configuration Design Support for Custom Providers
Although originally envisaged as a set of tools for use in Windows Forms (executable) applications, Enterprise Library from the Microsoft patterns & practices (p&p) group is proving popular with Web developers as well. In particular, the Data Access Application Block, Cryptography Application Block, and Logging Application Block can simplify development of complex applications.
This article describes how you can use these blocks, and the Caching Application Block, in your ASP.NET applications. The example you will see is relatively simple, designed to demonstrate how you configure and interact with Enterprise Library, and does not explore all of the many features of the blocks. Instead, this series of articles will provide you with a guide to getting started using Enterprise Library in ASP.NET, and help you understand how you can make best use of the blocks and extend them to suit your own requirements.
The example application consists of a single ASP.NET Web page that makes use of four of the six application blocks:
· It uses the Data Access Application Block to fetch rowsets from a database, using both SqlClient and OLE-DB providers, and returning both a DataReader and a DataSet.
· It uses the Caching Application Block to store both a DataSet and an encoded Byte array in Isolated Storage on the local machine, and retrieve it from the cache on demand.
· It uses the Cryptography Application Block to create a hash of a string value, and to encrypt and decrypt the string value using the Rijndael algorithm.
· It uses the Logging Application Block to write entries to the Windows Event Log if an error occurs when accessing the database.
While the application does not use the Security Application Block or the Exception Handling Application Block, the way that you configure and use these blocks follows the same basic pattern as those you will see in the example application. One of the features of Enterprise Library is a consistent approach to the way that the blocks expose features, making it easy to take advantage of all the blocks once you have mastered working with one of them.
Figure 1 shows the example application displaying data extracted from a database, the contents of the DataSet stored and then retrieved from the cache, and the encrypted version of the text from the textbox above the Get Hash, Encrypt, and Decrypt buttons.

Figure 1 - The example application that demonstrates using Enterprise Library in ASP.NET
Of course, you can use the application blocks and the other features of Enterprise Library in other tiers of your application as well. For example, if you expose your data through a business layer or data access layer (or both), you can use the Data Access Application Block in your middle-tier components to interact with the database, and the Caching Application Block to cache the data. In this scenario, you can also use the Logging Application Block to help you implement instrumentation for monitoring application performance and behavior, and the Exception Handling Application Block to implement a standardized approach to handling errors.
The easiest and the recommended approach for adding Enterprise Library features to your application is the Configuration Console. This graphical tool makes it easy to add individual blocks and other Enterprise Library features such as instrumentation to an application by automatically updating the application's configuration file.
Simply create a new Web site in Visual Studio, which creates a new default Web.config file. Then open this file into the Configuration Console. If you have an existing Web site or Web application that contains a Web.config file, you can open this in the Configuration Console. Changes made by the Configuration Console do not affect other configuration settings within the Web.config file. Alternatively, you can create a new Web.config file within the Configuration Console.
Start the Configuration Console from the Enterprise Library section of your Start menu by selecting Enterprise Library Configuration. To create a new configuration file, right-click the Enterprise Library Configuration node in the left-hand tree view and select New Application or select New Application on the File menu. If you already have a Web.config file, click the Open Existing Application icon on the toolbar or select Open Application on the File menu and load it into the console.
If you create a new configuration, or open a configuration file where you have not already added Enterprise Library features, you will see just the Application Configuration node at this point. Right-click on this node and select New, then select the application block or the features (such as Configuration Sources or Instrumentation) that you want to add (see Figure 2).

Figure 2 - Adding an application block or feature to the configuration
Adding a block or feature to the configuration automatically adds sensible defaults for that block or feature. For example, if you add the Data Access Application Block, the console adds a Connection Strings node and - below that - a Connection String node with child nodes for its Database, Server, and Integrated Security properties. You can select these property nodes and edit the values in the right-hand window. You can also select the Connection String node and edit its name (this is the name you will refer to this database connection with in your code), and edit the ProviderName property (the default is System.Data.SqlClient).
The property editor entries in the right-hand window use a range of controls to help you specify or select the appropriate values. For example, the ProviderName property uses a drop-down list to select the provider from those installed on your machine. Notice also that, when you click on the Data Access Application Block node in the tree view, you can expand the values in a tree view control that appears in the right-hand window to modify properties of the application block. In the case of the Data Access Application Block, you can select which of the database connections (the connection string nodes in the Connection Strings section) is the default for the block (see Figure 3).

Figure 3 - Editing properties of the Data Access Application Block
To add more database connections to the configuration, right-click on the Connection Strings node and select New then Connection String. Modify the values for the name of the new Connection String node, and its Database, Server, and Integrated Security properties. You can also add new properties, and remove existing properties, where this is valid for the section you are editing.
For example, you can remove the Integrated Security node from the tree view and replace it with the UserID and Password properties if this is required for your connection. Figure 4 shows a second database connection named SecondConnection added to the configuration of the Data Access Application Block node, with the ProviderName changed to System.Data.OleDb.

Figure 4 - Adding a second database connection for an OLE-DB connection
Once you have completed configuration of the blocks and features you want to add to your application, select Save Application from the File menu to update your Web.config file. If you created a new configuration in the console, it prompts for the path and name for the configuration file. If you then open the file in a text editor or in Visual Studio, you will see what the console added to it. For the entries shown in the previous screenshots, it adds the appropriate <configSections> entry that specifies the class to handle the configuration data (in this case the class DatabaseSettings from the Microsoft.Practices.EnterpriseLibrary.Data.Configuration namespace). It also adds a <dataConfiguration> section that specifies the default database connection. Then it creates the connection strings for each database connection you added to the configuration, and stores them in the standard <connectionStrings> section:
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices...DatabaseSettings,
Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=null" />
</configSections>
<dataConfiguration defaultDatabase="MyDefaultConnection" />
<connectionStrings>
<add name="SecondConnection"
connectionString="Database=Database;Server=.;UserID=me;Password=secret;"
providerName="System.Data.OleDb" />
<add name="MyDefaultConnection"
connectionString="Database=Database;Server=(local);
Integrated Security=SSPI;"
providerName="System.Data.SqlClient" />
</connectionStrings>
The process for adding and configuring other application blocks and features is almost identical to that shown above for the Data Access Application Block. You need to understand what each type of node does, of course, so that you can create the configuration you need. However, in general, this is a reasonably intuitive process.
For example, the Caching Application Block exposes a Cache Manager collection, with each member configured to use a single backing store. In the example application, there is a single Cache Manager, which uses the Isolated Storage backing store.
The Cryptography Application Block exposes a Hash Providers collection and a Symmetric Providers collection. You can add one or more providers of the appropriate type to each collection. As you add a provider, the Configuration Console helps you to configure it. When you add a new Hash Algorithm Provider, a dialog appears allowing you to select the algorithm class you require, or you can load a separate assembly and select a suitable provider from that assembly (see Figure 5).

Figure 5 - Selecting a Hash Algorithm Provider for the Cryptography Application Block
When you add a new Symmetric Algorithm Provider, you can choose the use of the standard symmetric encryption algorithms, or the DPAPI Windows algorithm. For all except the DPAPI provider, a Wizard collects all the required information for implementing the encryption algorithm you want to use. This includes selecting the algorithm type (such as DES, TripleDES, and Rijndael), creating the key, and saving the key file.
One of the most complex blocks is the Logging Application Block. When you add this to your configuration, the console adds nodes for Filters, Formatters, Category Sources, Special Sources, and Trace Listeners. Figure 6 shows the default settings that automatically allow you to write to the Windows Event Log. You can see the Formatted Event Log TraceListener, complete with the default Text Formatter (defined in the Formatters section) that takes the information extracted automatically from the .NET Framework and generates strings for the Event Log message.

Figure 6 - Configuring the Logging Application Block
The Enterprise Library Documentation describes the configuration schema for each block, and the usage of each type of object that you can add to your configuration. It also discusses the overall aims of each block, the design considerations, and how you can use it in your applications.
In the following sections of this article, you will see how the example application uses the Data Access Application Block, Logging Application Block, Caching Application Block, and Cryptography Application Block. There is not room to discuss every method of every block, but you will find a full reference to these methods in the Enterprise Library Documentation. Look for topics starting with "Developing with ..." within the sections of guidance for each block.
Before you can write code to use the application blocks or other features of Enterprise Library, you must add references to the appropriate assemblies to your project, and references to the appropriate namespaces to your code. As in the .NET Framework, the name of each Enterprise Library assembly is the same as the namespace name. Therefore, you must reference one or more of these assemblies, which by default are located in your %Program Files%\Microsoft Enterprise Library January 2006\bin folder:
· Microsoft.Practices.EnterpriseLibrary.Caching.dll
· Microsoft.Practices.EnterpriseLibrary.Security.dll
· Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.dll
· Microsoft.Practices.EnterpriseLibrary.Data.dll
· Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.dll
· Microsoft.Practices.EnterpriseLibrary.Logging.dll
In all cases, you must also reference the core assemblies for Enterprise Library as well:
· Microsoft.Practices.EnterpriseLibrary.Common.dll
· Microsoft.Practices.EnterpriseLibrary.ObjectBuilder.dll
Then you add the namespace references to your application code classes for the application blocks you want to use:
' for Caching Application Block
Imports Microsoft.Practices.EnterpriseLibrary.Caching
Imports Microsoft.Practices.EnterpriseLibrary.Caching.Expirations
' for Cryptography Application Block
Imports Microsoft.Practices.EnterpriseLibrary.Security.Cryptography
' for Data Access Application Block and using DataSet and DataReader
Imports Microsoft.Practices.EnterpriseLibrary.Data
Imports System.Data
Imports System.Data.Common
' for Exception Handling Application Block
Imports Microsoft.Practices.EnterpriseLibrary.ExceptionHandling
' for Logging Application Block
Imports Microsoft.Practices.EnterpriseLibrary.Logging
Imports Microsoft.Practices.EnterpriseLibrary.Logging.ExtraInformation
Imports Microsoft.Practices.EnterpriseLibrary.Logging.Filters
' for Security Application Block
Imports Microsoft.Practices.EnterpriseLibrary.Security
' to use the Instrumentation features of Enterprise Lilbrary
Imports System.Diagnostics
The example application uses the Data Access Application Block to retrieve data from a database using both the SqlClient and OleDb providers. The top section of the page contains two list boxes populated with a list of products from the Northwind database. The code in the two routines, which are called from the Page_Load event handler, extracts the data as DataReader instances using simple declarative SQL commands.
The application configuration for the Data Access Application Block contains two Connection String entries, named LocalSqlConnection and LocalOleDbConnection, with their Database, Server, and Integrated Security properties set to access a local SQL Server database. Enterprise Library uses a class named to Database to reference each connection string you configure for the Data Access Application Block, and exposes a static class named DatabaseFactory that you can use to generate Database instances.
Therefore, the first routine in the page, named PopulateSqlListBox, simply creates a new Database instance by calling the DatabaseFactory.CreateDatabase method and specifying the required connection. Then it declares the SQL statement and uses it to create a DbCommand instance by calling the GetSqlStringCommand method of the Database instance. Code in the Data Access Application Block automatically creates the appropriate connection, and applies the appropriate properties to the command. All that remains is to execute the command, and the code does this by calling the ExecuteReader method of the Database instance to get back an instance of a class that implements IDataReader (in fact, a DataReader instance). Notice that, following best practice, the code uses a Using construct to ensure that the reader is correctly closed and disposed after use. The reader is then used to populate the left-hand list box on the page:
Sub PopulateSqlListBox()
Try
' use SqlClient Database class from Data Access Block
Dim db As Database = DatabaseFactory.CreateDatabase("LocalSqlConnection")
Dim sql As String = "SELECT ProductName FROM Products"
' create a Command and execute it to get a DataReader
Dim cmd As DbCommand = db.GetSqlStringCommand(sql)
Using reader As IDataReader = db.ExecuteReader(cmd)
' populate the first ListBox
ListBox1.DataSource = reader
ListBox1.DataBind()
End Using
Catch ex As Exception
lblError.Text = ex.Message
End Try
End Sub
The second routine populates the right-hand list box on the page. The code is similar to that shown above, but this time it uses the LocalOleDbConnection database connection:
Sub PopulateOleDbListBox()
Try
' use OleDb Database class from Data Access Block
Dim db As Database = DatabaseFactory.CreateDatabase("LocalOleDbConnection")
Dim sql As String = "SELECT ProductName FROM Products"
' create a Command and execute it to get a DataReader
Dim cmd As DbCommand = db.GetSqlStringCommand(sql)
Using reader As IDataReader = db.ExecuteReader(cmd)
' populate the second ListBox
ListBox2.DataSource = reader
ListBox2.DataBind()
End Using
Catch ex As Exception
lblError.Text = ex.Message
Try
' use the Logging Application Block
' to create Windows Event Log entry
' as shown in following section
...
Catch iex As Exception
lblError.Text &= "<br />" & iex.Message
End Try
End Try
End Sub
The other difference is that this routine uses the Logging Application Block to write details of any exception to the Windows Event Log. You will see the code that does this in a later section of this article.
The example application also uses the Data Access Application Block to generate a DataSet in the section of code that demonstrates use of the Caching Application Block (you will see the code for this section of the application in a later section of this article). As in the previous listings, the code first generates an instance of the Database class using the appropriate database connection - in this case the LocalSqlConnection.
However, this time the data is extracted using a stored procedure within the database, rather than a declarative SQL statement. After declaring the stored procedure name, the code generates a suitable command from the Database instance. Because it will call a stored procedure, the code uses the GetStoredProcCommand method rather than the GetSqlStringCommand method you saw in the previous listings.
As the stored procedure takes parameters, the code must also specify these. The Data Access Application Block makes this easy by exposing a range of methods for creating parameters and adding them to the command in one operation. In this case the code uses the AddInParameter method of the Database class to generate two input parameters named Beginning_Date and Ending_Date, both of type DateTime, and with values appropriate for extracting a set of rows from the database.
Finally, the code calls the ExecuteDataSet method of the Database class to get back a DataSet populated with the results of executing the "Employee Sales by Country" stored procedure:
' use SqlClient Database class from Data Access Block
Dim db As Database = DatabaseFactory.CreateDatabase("LocalSqlConnection")
Dim queryName As String = "Employee Sales by Country"
' create a Command for a stored procedure and add parameters
Dim cmd As DbCommand = db.GetStoredProcCommand(queryName)
db.AddInParameter(cmd, "Beginning_Date", DbType.DateTime, New DateTime(1997, 1, 1))
db.AddInParameter(cmd, "Ending_Date", DbType.DateTime, New DateTime(1997, 12, 31))
' execute the command to get a DataSet
Dim ds As DataSet = db.ExecuteDataSet(cmd)
Figure 7 shows the results in the browser. You can see the two list boxes populated with lists of products, and the contents of the DataSet displayed within an ASP.NET GridView control.

Figure 7 - Using the Data Access Application Block to populate the list boxes and create a DataSet for use by the Caching Application Block
The Database class is the core class you use to interact with the Data Access Application Block, and it exposes around twenty methods. These include:
· Methods for creating and updating parameters: AddInParameter, AddOutParameter, AddParameter, BuildParameterName, ClearParameterCache, DiscoverParameters, GetParameterValue, and SetParameterValue.
· Methods for retrieving and updating data: ExecuteDataSet, ExecuteNonQuery, ExecuteReader, ExecuteScalar, LoadDataSet, and UpdateDataSet.
· Methods for accessing connections and commands: CreateConnection, GetDataAdapter, GetSqlStringCommand, GetStoredProcCommand, and GetStoredProcCommandWithSourceColumns.
In the previous section, you saw that the routine that populates the right-hand list box uses the Logging Application Block to write an entry in the Windows Event Log if an error occurs. For example, if you edit the source code for the application so that the SQL statement in the PopulateOleDbListBox routine refers to a non-existent table in the database, the code will raise an exception. The example page displays the exception message, and indicates that it was also stored in the Application Event Log (see Figure 8).

Figure 8 - An error when populating the right-hand list box writes an entry in Windows Event Log
Opening Event Viewer from the Administrative Tools section of your Start menu shows the new entry. Opening the entry reveals the details of the error, as created by the Logging Application Block (see Figure 9).

Figure 9 - The Event Log entry created when a table does not exist in the target database
The code to create the Event Log entry is extremely simple. Within the Catch block of the PopulateOleDbListBox routine is this code:
...
Catch ex As Exception
lblError.Text = ex.Message
Try
' use the Logging Application Block
Dim log As LogEntry = New LogEntry()
log.EventId = 6001
log.Message = ex.Message
log.Severity = TraceEventType.Error
log.Priority = 5
' write an entry to the Application Event Log
Logger.Write(log)
lblError.Text &= "<br />Written to Application Event Log"
Catch iex As Exception
lblError.Text &= "<br />" & iex.Message
End Try
End Try
End Sub
You can see from this that all the code has to do is create a new LogEntry instance (a class defined within the Logging Application Block), and set its properties. Then it calls the Write method of the static Logger class and passes to it the LogEntry to write. A Try...Catch construct around this code prevents an exception when writing to the Event Log from interrupting program execution, and instead displays a warning message. This may occur if you are writing to a remote log and the connection fails, or if the code does not have the required permission.
The LogEntry and Logger classes are the main classes you will use to write to the Event Log. Both expose several methods (and, in the case of the LogEntry class, a large number of properties) that you can use to tailor the messages and behaviour. You can also use the Logging Application Block to:
· Generate email messages
· Submit messages to a database or a message queue
· Create a text file
· Expose a WMI event
· Filter specific messages
· Deliver messages synchronously or asynchronously
For more details, consult the Enterprise Library Documentation.
The example application demonstrates use of the Caching Application Block by caching a DataSet generated with the Data Access Application Block using the default Isolated Storage backing store provider. When you click the button in the example application, it creates the DataSet, caches it, and then displays the number of items in the cache (see Figure 10).

Figure 10 - Using the Caching Application Block to cache a DataSet
The following listing shows the code that accomplishes this. The first part of the code that creates the DataSet, shown in the earlier section on the Data Access Application Block, is not repeated here. After creating the DataSet, the code creates an instance of the default CacheManager class using the GetCacheManager method of the static CacheFactory class.
Protected Sub btnCache_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCache.Click
Try
' use SqlClient Database class from Data Access Block
' to create a DataSet, as shown in earlier section
...
' use the Caching Application Block
Dim diskCache As CacheManager
' use default (Isolated Storage) cache provider
diskCache = CacheFactory.GetCacheManager()
' store the Dataset in the Isolated Storage cache
diskCache.Add("SalesDataset", ds, CacheItemPriority.Normal, Nothing, _
New SlidingTime(TimeSpan.FromSeconds(30)))
lblCount.Text = String.Format("Cache contains {0} item(s)<br />", diskCache.Count)
Catch ex As Exception
lblError.Text = ex.Message
End Try
End Sub
After creating the CacheManager instance, the code calls the Add method to add the DataSet to the cache. It specifies the cache key name ("SalesDataSet"), the DataSet to cache, and a cache priority. The third parameter, set to Nothing in this example, can be a reference to a class that implements the ICacheItemRefreshAction interface, and which refreshes the item in the cache.
To specify the expiry rule for the cached item, you pass an array containing one or more instances of a class that implements the ICacheItemExpiration interface. These can be instances of the AbsoluteTime, SlidingTime, FileDependency, or NeverExpired classes, reflecting different types of expiration policy.
Finally, the code displays the value of the Count property of the CacheManager instance to show how many items are in the cache. If you create an encrypted version of a string in the sample application (as demonstrated in the next section), this is also cached - and you will see that the Count property returns 2 in this case.
To extract an item from the cache is a similar process, but uses the GetData method of the CacheManager, which returns the cached item as an Object data type. You can then cast it to the required type, and - in this example - use it to populate the GridView control on the page. If the item is not found in the cache, the GetData method returns Nothing (null in C#):
Protected Sub btnFetch_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnFetch.Click
Try
' use the Caching Application Block
Dim diskCache As CacheManager
' use default (Isolated Storage) cache provider
diskCache = CacheFactory.GetCacheManager()
' retrieve the Dataset from the Isolated Storage cache
Dim ds As DataSet = DirectCast(diskCache.GetData("SalesDataset"), DataSet)
If ds Is Nothing Then
lblError.Text = "Dataset not found in Cache"
Else
' populate the GridView
GridView1.DataSource = ds.Tables(0)
GridView1.DataBind()
End If
Catch ex As Exception
lblError.Text = ex.Message
End Try
End Sub
Figure 11 shows the result in the example application - you can see the GridView containing the cached data below the two buttons.

Figure 11 - Retrieving the DataSet from the cache
The CacheManager class also exposes the Contains method that checks if the cache contains a specific item, the Remove method to remove a specified item, and the Flush method to remove all items. You can also create instances of the CacheItem class directly and pass them to the Add method of the CacheManager class. Use the Configuration Console to specify the default properties for the cache scavenging interval and the polling time.
Creating hashes, and encrypting and decrypting data, can be onerous tasks if you use the classes in the .NET Framework directly. The Cryptography Application Block makes these tasks much easier, and yet offers considerable flexibility in the choice of algorithm.
The example application uses the Cryptography Application Block configured with the SHA1 hashing algorithm and the Rijndael symmetric encryption algorithm. When you click the Hash button in the example page, code creates a SHA1 hash of the text in the text box above the buttons, and displays it in the text box below the buttons (see Figure 12).

Figure 12 - Creating a hash with the Cryptography Application Block
To create the hash, the code first uses the GetBytes method of the .NET Framework Encoding.UTF8 class to generate a Byte array that represents the string value in the first text box. It then passes this value to the CreateHash method of the static Cryptographer class in the Cryptography Application Block. Because you can use the Configuration Console to configure more than one Hash Provider, you must also specify the name of the configured provider you want the method to use. The result is also a Byte array, which the code then converts to a Base64 encoded String for display in the page by using the ToBase64String method of the .NET Framework Convert class:
Protected Sub btnHash_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnHash.Click
lblCrypt.Text = String.Empty
Try
Dim valueToHash As Byte() = Encoding.UTF8.GetBytes(TextBox1.Text)
' use SHA1 Managed Hash Provider through Cryptography Block
Dim generatedHash As Byte() = Cryptographer.CreateHash("SHA1Managed", valueToHash)
' convert to Base 64 for display
lblCrypt.Text = Convert.ToBase64String(generatedHash)
Catch ex As Exception
lblError.Text = ex.Message
End Try
End Sub
The example application also demonstrates use of a symmetric encryption provider with the Cryptography Application Block. When you click the Encrypt button in the example page, code creates a Rijndael encrypted version of the text in the text box above the buttons, and displays it in the text box below the buttons (see Figure 13).

Figure 13 - Encrypting a String with the Cryptography Application Block
The next listing shows the code to achieve this. As with the hash generating code in the previous section, this code first converts the String from the text box into a Byte array. Then it calls the EncryptSymmetric method of the static Cryptographer class, specifying the name of the Symmetric Encryption Provider to use (you can configure more than one in your application), and the Byte array.
So that you can see the result of decrypting the value, the code must persist the encrypted Byte array across postbacks. As the application already uses the Caching Application Block, it is easy to use this to cache the Byte array as well. The Byte array is cached with the key "EncryptedText" for an absolute period of five seconds. The code then converts the Byte array into a Base64 encoded string for display in the page:
Protected Sub btnEncrypt_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnEncrypt.Click
lblCrypt.Text = String.Empty
Try
Dim valueToEncrypt As Byte() = Encoding.UTF8.GetBytes(TextBox1.Text)
' use Rijndael Symmetric Encryption Provider through Cryptography Block
Dim generatedSecret As Byte() = Cryptographer.EncryptSymmetric("RijndaelManaged", _
valueToEncrypt)
' use the Caching Application Block
Dim diskCache As CacheManager = CacheFactory.GetCacheManager()
' store the generated secret in the Isolated Storage cache
diskCache.Add("EncryptedText", generatedSecret, CacheItemPriority.Normal, Nothing, _
New AbsoluteTime(DateAdd(DateInterval.Second, 5, DateTime.Now)))
' display Base64 encoded version of generated secret
lblCrypt.Text = Convert.ToBase64String(generatedSecret)
Catch ex As Exception
lblError.Text = ex.Message
End Try
End Sub
When you click the Decrypt button in the example page, code uses the Rijndael Symmetric provider to decrypt the encrypted version of the text cached by the Caching Application Block, and displays the decrypted version in the text box below the buttons (see Figure 14).

Figure 14 - Decrypting a String with the Cryptography Application Block
The code is just the reverse of that used in the previous listing to encrypt the String value. It extracts the encrypted value from the Caching Application Block cache using the GetData method, which returns it as an Object data type, and casts it to a Byte array. It then passes the Byte array to the DecryptSymmetric method of the static Cryptographer class to get back the decrypted version - also as a Byte array. The array is then converted to a String, and displayed in the page:
Protected Sub btnDecrypt_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDecrypt.Click
lblCrypt.Text = String.Empty
Try
' use the Caching Application Block
Dim diskCache As CacheManager = CacheFactory.GetCacheManager()
' retrieve the generated secret from the Isolated Storage cache
Dim valueToDecrypt As Byte() = DirectCast(diskCache.GetData("EncryptedText"), Byte())
' use Rijndael Symmetric Encryption Provider through Cryptography Block
Dim decryptedSecret As Byte() = Cryptographer.DecryptSymmetric("RijndaelManaged", _
valueToDecrypt)
' display the decrypted text
lblCrypt.Text = Encoding.UTF8.GetString(decryptedSecret)
Catch ex As Exception
lblError.Text = ex.Message
End Try
End Sub
Although the example you have seen is relatively simple, you should now see how easy it is to use the features and application blocks in Enterprise Library. These can simplify considerably some of the complex tasks you may need to accomplish in your Web applications or middle-tier components. The example demonstrates accessing databases, caching data, writing to the Windows Event Log, creating hash values, and encrypting and decrypting data.
In future articles in this series, you will see this application again - used to demonstrate running Enterprise Library in partial trust mode, and creating a custom cache provider more suited to use in ASP.NET applications.
· Go to Part 3 - Using Enterprise Library in ASP.NET Partial Trust Mode
©2006 Alex Homer – alex@stonebroom.com