Bu makalenin Türkçe versiyonunu görmek için Tıklayınız.
In this article I will try to explain Custom Output Caching. Before diving into this subject let's remember the Output Caching in a short manner.
Output Caching - Partial Output Caching
In Asp.Net we use Output directive to cache our pages or some portion of the page. By using this directive in a page, we make all the page to be cached. And if we want to cache only a portion of the page we should seperate that portion as a usercontrol and put the Output directive in it. I will not explain the details of the output directive anymore. In the following Sample1 and Sample2 let's see some simple usages of it
Sample 1
In order to see the caching with naked eyes the samples are prepared to show the time-clock of the server on the page.
Html-ascx :
<%@ Control Language="vb" AutoEventWireup="false" Codebehind="ClockForMethod1.ascx.vb" Inherits="PartialCachingSite.ClockForMethod1" %>
<%@ OutputCache Duration="3" VaryByParam="*" VaryByControl="*" VaryByCustom="*" %>
<span id="spnTime" runat="server"></span>
Codebehind :
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
spnTime.InnerText = Now.ToLongTimeString
End Sub
In Sample 1, we created a usercontrol, showing the server time, and using this control in a page. As you see above, the usercontrol is cached for a period of 3 seconds, therefore it does not matter how frequently you requested the, the time seen on the page will change after 3 seconds.
Attention: In the above sample we have seen the usage of Output directive in aspx file of the page. We can also gain the same functionality in the codebehind by using the PartialCaching attribute. You can see it in Sample 2. The most of the parameters of the Output directive are also available for PartialCaching attribute, which are Duration, VaryByParams, VaryByControls, sqlDependency, Shared.
Sample 2
Html-ascx :
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="ClockForMethod2.ascx.vb" Inherits="PartialCachingSite.ClockForMethod2" %>
<span id="spnTime" runat="server"></span>
Codebehind :
<PartialCaching(57, Nothing, Nothing, Nothing, False)> _
Partial Public Class ClockForMethod2
Inherits System.Web.UI.UserControl
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
spnTime.InnerText = Now.ToLongTimeString
End Sub
End Class
Custom Output Caching
Although I name it as Custom Output Caching, in fact it is not exactly caching of a web page. Because a page or a usercontrol that is cached in the previous requests is not executed on the server. I mean the life-cycle of the control(page or usercontrol) does not start. While debugging the page does not break into Page_Load or other methods. Beacuse the page or usercontrol is loaded from the cached html of it. Oppositely, in the following sample, that I have called as Custom Output Caching, the page is executed normally, but we will interfere to simulate caching.
Output Caching is the caching of the output of a page and that output is the rendered Html of the page. So, we can do this manuallay. To achieve this, we should get the rendered html of the usercontrol that we wanted to be cached and save it in some store such as sessionstate, applicationstate, viewstate ya da cache. For the following requests after the caching we block the page to be executed and output the saved html.
Now let's see this method in action.
Sample 3
Html-ascx:
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="ClockForMethod3.ascx.vb" Inherits="PartialCachingSite.ClockForMethod3" %>
<span id="spnTime" runat="server"></span>
Codebehind :
Partial Public Class ClockForMethod3
Inherits System.Web.UI.UserControl
Public ReadOnly Property isCached() As Boolean
Get
Return (HttpContext.Current.Cache.Get(Me.ClientID) Is Nothing = False AndAlso String.IsNullOrEmpty(HttpContext.Current.Cache.Get(Me.ClientID).ToString) = False)
End Get
End Property
Public Property myCacheDuration() As TimeSpan
Get
Dim dur As TimeSpan = Me.ViewState("myCacheDuration")
If dur = Nothing Then
Return New TimeSpan(0, 0, 13)
Else
Return dur
End If
End Get
Set(ByVal value As TimeSpan)
Me.ViewState("myCacheDuration") = value
End Set
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If isCached = False Then
spnTime.InnerText = Now.ToLongTimeString
End If
End Sub
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
Dim myCachedHtml As String = String.Empty
If HttpContext.Current.Cache.Get(Me.ClientID) Is Nothing = False Then
myCachedHtml = HttpContext.Current.Cache.Get(Me.ClientID).ToString
End If
If String.IsNullOrEmpty(myCachedHtml) = False Then
writer.Write(myCachedHtml)
Else
Dim sb As New Text.StringBuilder
Dim tw As New IO.StringWriter(sb)
Dim hw As New HtmlTextWriter(tw)
MyBase.Render(hw)
HttpContext.Current.Cache.Insert(Me.ClientID, sb.ToString(), Nothing, Now.Add(myCacheDuration), Web.Caching.Cache.NoSlidingExpiration, Caching.CacheItemPriority.Normal, Nothing)
writer.Write(sb.ToString())
End If
End Sub
End Class
Result
To say the truth the normal Output Caching method has more performance, flexibility and simple usage etc than the custom Output Caching. But it can be useful in some situations that you need special things to do in caching logic, because you have the full control.
You can see the samples given in this article in the attached file.
PartialCachingSite.zip (46,58 kb)