How to manage the ASP.NET web service data caching in C#

Data caching, supported by ASP.NET, allows you to store full-fledged object in the cache. You can use data caching through the Cache object which is available through the Context.Cache property in your web service code. With this object you can temporarily store information that is expensive to create that the web method can reuse it for other calls by other clients.

You can create a BooksService that provides two GetBooks() methods, one of which accepts an author parameter.  To ensure best possible performance but cut down on the amount of data in the cache, you can store in the cache as a single object the full books DataSet. Then, when a client calls the version of GetBooks() that requires an author parameter, you need to filter out the rows for the author the client requested.

The following code shows this approach at work. The first step is to create a private method that uses the cache, called GetBooksDataSet():

 

private DataSet GetBooksDataSet()

{

DataSet ds;

if (Context.Cache[“BooksDataSet”] != null)

{

// Retrieve it from the cache

ds = (DataSet)Context.Cache[“BooksDataSet”];

}

else

{

// Retrieve it from the database.

string sql = “SELECT ISBN, Title, AuthorFName, AuthorLName, Price FROM Books” ;

SqlConnection con = new SqlConnection(connectionString);

SqlDataAdapter da = new SqlDataAdapter(sql, con);

ds = new DataSet();

da.Fill(ds, “Books”);

 

// Track when the DataSet was created. You can retrieve this information in your client

// to test that caching is working.

ds.ExtendedProperties.Add(“CreatedDate”, DateTime.Now);

 

// Store it in the cache for ten minutes.

Context.Cache.Insert(“BooksDataSet”, ds, null,

DateTime.Now.AddMinutes(10), TimeSpan.Zero);

}

return ds;

}

Both the GetBooks() and GetBooksByAuthor() methods can use the private GetBooksDataSet() method. The difference is that GetBooksByAuthor () loops through the records and manually removes each record that doesn’t match the author. Here are both versions:

 

[WebMethod(Description=”Returns the full list of books.”)]

public DataSet GetBooks()

{

return GetBooksDataSet();

}

 

[WebMethod(Description=”Returns the full list of books by author.”)]

public DataSet GetBooksByAuthor(string authorFName, string authorLName)

{

// Copy the DataSet.

DataSet dsFiltered = GetBooksDataSet().Copy();

 

// Remove the rows manually.

// In this way you can protect your code to SQL injection attacks,

// instead than using the DataTable.Select() method

 

foreach (DataRow row in dsFiltered.Tables[0].Rows)

{

// Perform a case-insensitive compare.

if ( (String.Compare(row[“AuthorFName”].ToString(),authorFName.ToUpper(), true) != 0) &&

(String.Compare(row[“AuthorLName”].ToString(),authorLName.ToUpper(), true) != 0) )

{

row.Delete();

}

}

// Remove these rows permanently.

dsFiltered.AcceptChanges();

return dsFiltered;

}

Note: You should specify the amount of time to cache information depending on how long the underlying data will remain valid.