Caching Page Output with File Dependencies

When you add a page to the output cache, the page will be removed when the amount of time you specify in the expiration policy has passed. There are times when you want a page, or versions of a page, to be removed from the output cache before it has expired. To do this, you can use the HttpResponse.AddFileDependency method to make the cached page dependent on a single file, or the HttpResponse.AddFileDependencies method to make the cached page dependent upon a group of files represented by an ArrayList object.

For example, if you use XML files as data stores for your page, you create an ArrayList that contains the names of all the files that the page uses. You can then call AddFileDependencies to make the page dependent upon that ArrayList. When any of the XML files change, the page is removed from the output cache and a new page is generated upon the next request.

Note   You cannot use these methods from a Web Forms user control.

Note   You can explicitly remove any page from the output cache by calling the HttpResponse.RemoveOutputCacheItem method. You can do this from the global.asax file, from a custom ASP.NET server control you have created, or from a page, depending on the needs of your application.

To make cached page output dependent upon a file

  1. Specify the settings for caching page output either declaratively or programmatically. For more information, see Setting Expirations for Page Caching, Setting the Cacheability of a Page, and Caching Multiple Versions of a Page.

  2. In the code-declaration block or the code-behind file for the page, create a String object. This will be passed as the parameter argument in the AddFileDependency method call.

    static string filePath;
    [Visual Basic]
    Shared filePath As [String]
    
  3. In the Page_Load method, or another ASP.NET page lifecycle method, set the string you created in step 2 to the absolute path of the dependent file with the HttpServerUtility.MapPath method.

    filePath = Server.MapPath("authors.xml");
    [Visual Basic]
    filePath = Server.MapPath("authors.xml")
    
  4. In the same page lifecycle method you used in step 3, access Response property syntax to call the AddFileDependency method, passing the String object you created in Step 2 in the filename parameter.

    Response.AddFileDependency(filePath);
    [Visual Basic]
    Response.AddFileDependency(filePath)
    

To make cached page output dependent upon a group of files

  1. Specify the settings for caching page output either declaratively or programmatically. For more information, see Setting Expirations for Page Caching, Setting the Cacheability of a Page, and Caching Multiple Versions of a Page.

  2. In the code-declaration block or the code-behind file for the page, create an ArrayList object that contains the names of the dependent files.

    ArrayList depAL = new ArrayList();
    depAL.Add(Server.MapPath("authors.xml"));
    depAL.Add(Server.MapPath("products.xml"));
    [Visual Basic]
    Dim depAL As New ArrayList()
    depAL.Add(Server.MapPath("authors.xml"))
    depAL.Add(Server.MapPath("products.xml"))
    
  3. In one of the page lifecycle methods, such as Page_Load, use Response object syntax to call the AddFileDependencies method, passing the ArrayList object you created in Step 2 in the filenames parameter.

    Response.AddFileDependencies(depAL);
    [Visual Basic]
    Response.AddFileDependencies(depAL)
    

The following example uses the AddFileDependency method to make the cached page dependent upon an XML file, authors.xml. Once the page has been requested, it is stored in the output cache for 100 seconds. However, if the XML file changes before that amount of time elapses, the page output is removed from the cache. The next time the page is requested, a new version will be stored in the output cache. To test this, manually add another entry to the XML file after you request the page, and then refresh the page from your browser.

<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Data" %>
<%@ OutputCache duration="100" varybyparam="false" %>
<html>
  <script language="C#" runat="server">

    static String filePath;

    void Page_Load(Object Src, EventArgs E ) {

      filePath = Server.MapPath("Authors.xml");
      Response.AddFileDependency(filePath);
      LoadData();

      TimeMsg.Text = DateTime.Now.ToString("G");

    }
  
    void LoadData() {

        // Read the data from the XML source.
        DataSet ds = new DataSet();

        FileStream fs = new FileStream(Server.MapPath("authors.xml"), FileMode.Open,FileAccess.Read);
        StreamReader reader = new StreamReader(fs);
        ds.ReadXml(reader);
        fs.Close();

        // Create a DataView object to bind to 
        // the DataGrid on the page.
        DataView Source = new DataView(ds.Tables[0]);

       // Bind the Source to the DataGrid on the page.
      MyDataGrid.DataSource = Source;
      MyDataGrid.DataBind();
    }
  </script>
  <body>

    <form runat="server">

      <h3><font face="Verdana">File Dependencies</font></h3>

      <ASP:DataGrid id="MyDataGrid" runat="server"
        Width="300"
        BackColor="#ccccff"
        BorderColor="black"
        ShowFooter="false"
        CellPadding=3
        CellSpacing="0"
        Font-Name="Verdana"
        Font-Size="8pt"
        HeaderStyle-BackColor="#aaaadd"
      />
            <p>
      <i>Last generated on:</i> <asp:label id="TimeMsg" runat="server" />
    </form>
  </body>
</html>

[Visual Basic]
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Data" %>
<%@ OutputCache duration="100" varybyparam="false" %>
<html>

  <script language="VB" runat="server">
   ' Create a string to pass to AddFileDependency.
    Shared filePath As [String]


    Sub Page_Load(Src As [Object], E As EventArgs)
   
     ' Assign the string the absolute path to the
     ' dependent file, then pass it to AddFileDependency.
     filePath = Server.MapPath("Authors.xml")
     Response.AddFileDependency(filePath)
   
     ' Call this function to display XML data in the page.
     LoadData()
   
     TimeMsg.Text = DateTime.Now.ToString("G")
    End Sub 'Page_Load

   Sub LoadData()
   
     ' Read the data from the XML source.
     Dim ds As New DataSet()
   
     Dim fs As New FileStream(Server.MapPath("authors.xml"), FileMode.Open, FileAccess.Read)
     Dim reader As New StreamReader(fs)
     ds.ReadXml(reader)
     fs.Close()
   
     ' Create a DataView object to bind to 
     ' the DataGrid on the page.
     Dim [Source] As New DataView(ds.Tables(0))
   
     ' Bind the Source to the DataGrid on the page.
     MyDataGrid.DataSource = [Source]
     MyDataGrid.DataBind()
   End Sub 'LoadData
  </script>

  <body>
    <form runat="server">

      <h3><font face="Verdana">File Dependencies</font></h3>

      <ASP:DataGrid id="MyDataGrid" runat="server"
        Width="300"
        BackColor="#ccccff"
        BorderColor="black"
        ShowFooter="false"
        CellPadding=3
        CellSpacing="0"
        Font-Name="Verdana"
        Font-Size="8pt"
        HeaderStyle-BackColor="#aaaadd"
      />
<p>
      <i>Last generated on:</i> <asp:label id="TimeMsg" runat="server" />
    </form>
  </body>
</html>

The contents of the authors.xml file are as follows.

<NewDataSet>
  <Table>
    <au_id>172-32-1176</au_id>
    <au_lname>White</au_lname>
    <au_fname>Johnson</au_fname>
  </Table>

  <Table>
    <au_id>213-46-8915</au_id>
    <au_lname>Green</au_lname>
    <au_fname>Marjorie</au_fname>
  </Table>

</NewDataSet>

See Also

Caching ASP.NET Pages | HttpCacheability Enumeration | HttpCachePolicy Class | HttpResponse Class | @ OutputCache