The Caching API

The Caching API is much more flexible than the @OutputCache directive, in that you are in direct control of inserting items into cache and specifying exactly when and how they should be removed. For this reason, you will not run into as many issues while using the Caching API. The trade-off is that it is not quite as convenient and it takes a bit more code to get working. This section of the chapter helps you with some of the issues that you might encounter while using the Caching API.

Dependencies

Setting up dependencies for cached items is usually pretty straightforward. A couple situations, however, might be a bit confusing. When you are setting up a file dependency, you might get an error that looks like this:

							Exception Details: System.Web.HttpException: Invalid file name for monitoring: {0}

This error means that the Cache object cannot find the file that you want to base the dependency on. The cause of this error is almost always that you attempted to use a virtual path to your dependency file or that you just specified a filename, without a path. Unlike most other references in ASP.NET web applications, file dependencies require you to specify that absolute path to the file. An easy way to get the absolute path is to use the Server.MapPath() method call. The code in Listings 12.3 and 12.4 demonstrates both the incorrect and correct methods of specifying a file dependency.

Listing 12.3. Wrong and Right Ways to Use a File Dependency (C#)
<%@ Language="C#" %> 

<script language="C#" runat="server"> 
      protected void Page_Load(object sender, EventArgs e) 
      {
         //this causes an error 
         Cache.Insert("someKey", "someValue", 
               new CacheDependency("keyfile.txt")); 

         //this is the correct way 
         Cache.Insert("someKey", "someValue", 
               new CacheDependency(Server.MapPath("keyfile.txt"))); 
      } 
</script> 

Listing 12.4. Wrong and Right Ways to Use a File Dependency (Visual Basic .NET)
<%@ Language="VB" %> 

<script language="VB" runat="server"> 
      Protected Sub Page_Load(sender As Object, E As EventArgs) 
            'this causes an error 
            Cache.Insert("someKey", "someValue", _ 
                  new CacheDependency("keyfile.txt")) 

            'this is the correct way 
            Cache.Insert("someKey", "someValue", _ 
                  new CacheDependency(Server.MapPath("keyfile.txt"))) 
      End Sub 
</script> 

Some tricky situations can arise when you are attempting to set up a dependency based on another item in cache through its key. To do this, you use the overloaded signature of the CacheDependency class that accepts two parameters. Leave the first parameter null (unless you want the dependency to be file-based as well). The second parameter is an array of strings correlating to the keys upon which you want this cached item to be dependent. The tricky part comes in when you try to base the dependency on a single key. Ideally, you could just specify the single string value as a parameter. If you do this, however, you will get an error like this:

							Compiler Error Message: CS1502: The best overloaded method match for 'System.Web.Caching
.CacheDependency.CacheDependency(string[], string[])' has some invalid arguments 

or (Visual Basic .NET)

							Compiler Error Message: BC30311: A value of type 'String' cannot be converted to
 '1-dimensional Array of String'. 

Even though you are specifying only a single cache key as a dependency, it must still be in an array. Listings 12.5 and 12.6 provide examples of both incorrect and correct ways to handle a single-cache key dependency:

Listing 12.5. Wrong and Right Ways to Use a Single-Cache Key Dependency (C#)
<%@ Language="C#" %> 

<script language="C#" runat="server"> 
      protected void Page_Load(object sender, EventArgs e) 
      {
            //this causes an error 
            Cache.Insert("someKey", "someValue", 
            new CacheDependency(null, "depKey")); 

            //this is the correct way 
            string[] dependency = {"depKey"}; 

            Cache.Insert("someKey", "someValue", 
                  new CacheDependency(null, dependency)); 
      } 
</script> 

Listing 12.6. Wrong and Right Ways to Use a Single-Cache Key Dependency (Visual Basic .NET)
<%@ Language="VB" %> 

<script language="VB" runat="server"> 
      Protected Sub Page_Load(sender As Object, E As EventArgs) 
            'this causes an error 
            Cache.Insert("someKey", "someValue", _ 
                  new CacheDependency(Nothing, "depKey")) 

            'this is the correct way 
            Dim dependency As String() = {"depKey"} 

            Cache.Insert("someKey", "someValue", _ 
                  new CacheDependency(Nothing, dependency)) 
      End Sub 
</script> 

A final point about dependencies that might cause you problems is that the Cache object enables you to set up a dependency on a cache key that does not exist. This means that the item that you are trying to insert into the cache is immediately invalidated. One suggestion to avoid that situation is to check for the existence of an item in the cache before you use it as a dependency for another item. Interestingly, if you set up a file-based dependency based on a file that doesn’t exist, the item IS is inserted into the cache and can be referenced later.

Date and Time Expirations

Two of the overloaded signatures of the Insert method of the Cache class, as well as one signature of the Add method, enable you to specify an absolute expiration date/time for the cached item or a sliding expiration time. The key word to note in the previous sentence is or. If you attempt to specify both at the same time, you will get the following error message:

							Exception Details: System.ArgumentException: absoluteExpiration must be DateTime.MaxValue
 or slidingExpiration must be timeSpan.Zero. 

The error message tells you to use DateTime.MaxValue or TimeSpan.Zero so that only an absolute expiration or a sliding expiration is implemented. As an alternative, the Cache.NoAbsoluteExpiration constant can be used, which is equivalent to DateTime.MaxValue, and the Cache.NoSlidingExpiration constant can be used, which is equivalent to TimeSpan.Zero.

Retrieving Cached Items

Because all items returned from the cache are of the Object type, you must cast it to the appropriate type before assigning it, like this:

string someValue = Cache["someValue"]. ToString(); //C#

or

Dim someValue As String = Cache("someValue"). ToString() 'VB 

If you do not cast it to the proper type and you are not assigning the item from Cache to a variable of the Object type, you will get an error like this:

							Compiler Error Message: CS0029: Cannot implicitly convert type 'object' to 'string' 

If you attempt to retrieve an item from the cache using a key that doesn’t exist, it does not generate an error. Instead, it returns a null reference (Nothing, in Visual Basic .NET). If this is the case, then when you attempt to cast it to the proper type (as you just saw), you will get an error like this:

							Exception Details: System.NullReferenceException: Value null was found where an instance
 of an object was required. 

To get around this, always verify that the item that you want to retrieve from the cache exists. The following code demonstrates this:

//C# 
if(Cache[“someValue”] !!= null) 
{
         someValue = Cache[“someValue”]. ToString(); 
} 

or

'Visual Basic .NET 
If Cache("someValue") <> Nothing Then 
         someValue = Cache("someValue"). ToString() 
End If 

Removing Cached Items

You can run into trouble if you attempt to remove an item from the cache using an invalid key. This might happen more often than you think because you can never tell when a resource that the cached item is dependent on changes, thereby evicting it from the cache. Normally, the return value of the Remove method of the Cache class is the item that was removed from the cache. If the key is invalid, however, the return value is null (Nothing, in Visual Basic .NET). Therefore, if you plan to use the item that you are removing from the cache, you should verify that it exists first, using the same method demonstrated previously.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset