Declaratively enabling caching using OutputCache directive In this section, you will see how to enable output caching declaratively using the OutputCache directive. Here's the complete code of the ASP.NET page.
<%@ pagelanguage="C#"%>
<%@ OutputCacheduration="3600"varybyparam="none"sqldependency="Northwind:Categories"%>
<scriptrunat="server">
void
Page_Load(object sender, System.EventArgs e)
{
Response.Write("Page created on : " + DateTime.Now.ToString());
}
</script>
<html>
<headrunat="server">
<title>Declarative Output Caching</title>
</head>
<body>
<formrunat="server">
<asp:sqldatasourceid="categoriesSource"runat="server"selectcommand="Select
* from Categories"
providername="System.Data.OleDb"connectionstring="Provider=SQLOLEDB.1;Password=thiru;Persist
Security Info=True;User ID=sa;Initial Catalog=Northwind;Data
Source=localhost;Use Procedure for Prepare=1;Auto Translate=True;Packet
Size=4096;Workstation ID=THIRU-SERVER;Use Encryption for Data=False;Tag with
column collation when possible=False">
</asp:sqldatasource>
<asp:gridviewid="gridCategories"datasourceid="categoriesSource"runat="server"width="592px"height="160px">
</asp:gridview>
</form>
</body>
</html>
In the above code, you start by specifying the OutputCache directive at the top of the page. In the OutputCache directive, you specify the duration to which the page should be cached as well as the "none" value for the VaryByParam attribute that instructs ASP.NET to not cache multiple versions of the page based on parameters. Apart from these attributes, you also specify a new attribute named sqlcachedependency that is of the form <DatabaseName>:<TableName>. Because of this attribute, any time data in the Categories table of the Northwind database changes, the cached data will be automatically invalidated. The database name that you are specifying here should be defined in the connectionStrings section of the web.config file.
Then in the Page_Load event, you display the date and time the page was created using the Response.Write statement. Inside the HTML body element, you declare a SqlDataSource control that acts as the data source for a GridView control. While declaring the SqlDataSource control, you also specify the SelectCommand, ProviderName and ConnectionString attributes. The SelectCommand attribute allows you to specify the SQL command to be executed and the ProviderName attribute allows you to indicate the type of provider to use for connecting to the database. As the name suggests, the ConnectionString attribute allows you to specify the connection string to be used for establishing connection with the database. Finally, you also declare a GridView control that is associated with the SqlDataSource control using the DataSourceID attribute. By setting the DataSourceID attribute of the GridView to the ID of the SqlDataSource control, you can automatically display the data returned from the SqlDataSource.
Now that you understand the code, test the caching functionality by navigating to the page using the browser. When you do that, you will see an output that is somewhat similar to the following.

If you refresh the page again, you will see the same time in the displayed output, which is due to the fact that you have enabled output caching on the page. Now to test the SQL Server based trigger invalidation, change the data in the Categories table in the Northwind database and refresh the page. You should now see a change in the time displayed in the page. This clearly shows that the SQL Server based trigger invalidation mechanism automatically invalidates the cached page as soon as the data in the categories table changes.
Programmatic Output Caching
In the previous section, you saw how to use the declarative OutputCache directive to specify the caching dependency on a SQL Server table. In this section, you will see how to perform the same operation programmatically.
<%@ pagelanguage="C#"%>
<%@ importnamespace="System.Data"%>
<%@ importnamespace="System.Data.SqlClient"%>
<scriptrunat="server">
void
Page_Load(object sender, System.EventArgs e)
{
SqlConnection conn = new SqlConnection(
ConfigurationSettings.ConnectionStrings["Northwind"]);
SqlDataAdapter adapter = new
SqlDataAdapter("Select * from
Categories",conn);
DataSet categories = new DataSet();
adapter.Fill(categories);
SqlCacheDependency dependency = new
SqlCacheDependency("Northwind",
"Categories");
Response.AddCacheDependency(dependency);
Response.Cache.SetValidUntilExpires(true);
Response.Cache.SetExpires(DateTime.Now.AddMinutes(60));
Response.Cache.SetCacheability(HttpCacheability.Public);
gridCategories.DataSource = categories;
gridCategories.DataBind();
Response.Write("Page created on : " + DateTime.Now.ToString());
}
</script>
<html>
<headrunat="server">
<title>Programmatically Controlling Output
Cache</title>
</head>
<body>
<formrunat="server">
<asp:gridviewid="gridCategories"runat="server"
width="592px"height="160px">
</asp:gridview>
</form>
</body>
</html>
The above code is similar to the previous example except that the caching is performed programmatically. In the Page_Load event, you create an instance of the SqlConnection object and pass in the connection string as an argument. To retrieve the connection string from the web.config file, you use one of the new classes supplied by ASP.NET 2.0, named ConnectionStrings, that provides helper properties to retrieve the connection strings specified in the connectionStrings section of the web.config file. You then create an instance of the SqlDataAdapter object passing in the SQL to be executed and the SqlConnection object as its arguments. After that you create an instance of the DataSet object and then fill the dataset object by invoking the Fill method of the SqlDataAdapter object. Then you create an instance of the class named SqlCacheDependency passing in the database and the table to be monitored as its arguments. You also add the SqlCacheDependency object to the Response object using the AddCacheDependency method. After that, you set various attributes of the Cache object. Finally, you bind the output of the returned data to the GridView control. Navigating to the above page results in an output that is similar to our previous example. To test this page, change the data in the categories table and see the change in the date time displayed in the page.
Cache API Example
So far, you have seen how to use the output caching declaratively and programmatically to enable caching on ASP.NET pages. In this section, you will see how to use the Cache API to accomplish the same functionality. As in ASP.NET 1.x, the Cache API is very powerful in that it not only provides complete control over how items are cached but also enables the execution of some code when an item is removed or invalidated from the cache. The following code shows an example of using Cache API to control caching for an ASP.NET page.
<%@ pagelanguage="C#"%>
<%@ importnamespace="System.Data"%>
<%@ importnamespace="System.Data.SqlClient"%>
<scriptrunat="server">
void
Page_Load(object sender, System.EventArgs e)
{
DataSet categories;
categories = (DataSet)Cache["Categories"];
if
(categories == null)
{
SqlConnection conn = new
SqlConnection(
ConfigurationSettings.ConnectionStrings["Northwind"]);
SqlDataAdapter adapter = new
SqlDataAdapter("Select
* from Categories", conn);
categories = new DataSet();
adapter.Fill(categories);
SqlCacheDependency dependency = new
SqlCacheDependency("Northwind",
"Categories");
Cache.Insert("Categories", categories,
dependency);
Response.Write("Categories retrieved from the database");
}
else
Response.Write("Categories retrieved from the Cache");
gridCategories.DataSource = categories;
gridCategories.DataBind();
}
</script>
<html>
<headrunat="server">
<title>Using Cache API to store contents in
Cache</title>
</head>
<body>
<formrunat="server">
<asp:gridviewid="gridCategories"runat="server"width="592px"
height="160px">
</asp:gridview>
</form>
</body>
</html>
The above code is very similar to the previous example, except in this case, the Insert method of the Cache class is used to add items to the cache. In the above code, you start by creating an instance of the SqlConnection object passing in the connection string that is retrieved from the web.config file. Then you create an instance of the SqlDataAdapter object and pass in the SQL statement to be executed and the previously created SqlConnection object as its arguments. Then you execute the SQL query using the Fill method of the SqlDataAdapter object. After that you create an instance of the SqlCacheDependency object and supply the database name (that corresponds to the database name specified in the web.config file) and the table name as its arguments. Then you insert the categories dataset to the cache using the Insert method of the Cache object. At the time of inserting, you should also specify the SqlCacheDependency object so that the categories dataset can be invalidated when the data in the categories table changes. Finally, you sould bind the categories dataset to the GridView control.
When you navigate to the above page using the browser, you get the following output, which clearly shows that for the first time the categories information is retrieved from the database.

If you refresh the browser, you will see the following output, in which the categories information is retrieved from the cache.

To test if the SQL Server based cache invalidation mechanism works, modify the data in the Categories table and then if you navigate to the page using the browser, you will get a message stating that the categories is retrieved from the database.