WEBINAR:
On-Demand
Application Security Testing: An Integral Part of DevOps
Like many Web applications, performance is important for the sample application. Because the articles that make up the site change infrequently, you can easily cache article output by placing the following
OutputCache directive in the
article.aspx file.
<%@ OutputCache Duration="600"
VaryByParam="id" %>
Note that the
OutputCache directive uses the
VaryByParam attribute. That causes ASP.NET to cache the
article.aspx output several timesonce for each article identifier passed with the "id" parameter. The
Duration attribute value of
600 means the cache retains each cached copy for ten minutes (600 seconds) before refreshing the article from the database. Serving the pages from cache takes a significant load off the database and provides faster performance.
However, there is a problem with this caching scheme. If you load an article and then change the language using the drop-down list, you'll the
same article. The
VaryByParam setting maintains articles in the cache by the article ID, not by language. The
VaryByParam setting maintains articles in the cache by article id, not by language, so changing the language has no effect, as the cache will return the article in whichever language was requested first.
The solution to this problem lies in the
OutputCache directive's
VaryByCustom attribute. The standard use for
VaryByCustom is to set it to "browser," which directs the framework to cache a copy of the page each different web browser that hits the sitemeaning you can deliver browser-specific page versions. However, in this case, you're not interested in browser versions. Instead, you can use the
VaryByCustom attribute to cache the articles once for each language. To do this, you need to override the
GetVaryByCustomString() method in
global.asax.cs, which is where processing of the
VaryByCustom cache code occurs.
The
GetVaryByCustomString() method returns a string, and the framework maintains a cache copy for each different string. So, to create a cached copy of each article in each culture, you just need to return a unique code for each culturein this case the value of the
CulturePref cookie.
public override string GetVaryByCustomString(HttpContext context,
string arg)
{
switch (arg)
{
case "LanguageChoice":
string langChoice = "";
if (Request.Cookies["CulturePref"] != null)
{
langChoice =
Request.Cookies["CulturePref"].Value;
}
return "LanguageChoice=" + langChoice;
default:
return "";
}
}
To alter the way
article.aspx caches pages, add the
VaryByCustom attribute to the page.
<%@ OutputCache Duration="60" VaryByParam="id"
VaryByCustom="LanguageChoice" %>
If you now rebuild the application, refresh the page and change the language using the drop-down list you'll see that the caching occurs for each language. The application now benefits both from localization and from ASP.NET's output caching.