If you are using MOSS for a public facing internet site, the chances are you are using page output caching to increase scalability and performance. If you aren't you certainly should be. Page output caching is a feature of ASP.NET which MOSS overlays it's own control over the top.
Under site collection settings you can set up cache profiles which dictate how pages are cached and apply them to different parts of the site. You may have some areas which cache for several hours and other pages which only cache for a few minutes. Either way, not going through the full page rendering cycle for these pages if they are in output cache massively increases the number of visitors your site can support.
Often though you have a need to get some pages refreshed more quickly than just waiting for them to fall out of cache. Sure you can perform an app pool reset but that will take all pages out of cache and possibly lose users their session depending on your session management strategy.
It is possible to force an individual page to be removed from output cache and thus have it re-rendered immediately, useful for getting important content updates to users immediately.
The required call is the HttpResponse.RemoveOutputCacheItem() method which takes a parameter of a string for the site relative URL of the page you wish to remove from cache, e.g. /pages/landingpage.aspx
Given that this must occur within the application you are trying to clear a page from how do we call this ourselves? One approach is to create a custom layouts page which we can navigate to directly and enter the URL to get it cleared. As our public site is very likely set up with anonymous access we will need to ensure that the page inherits from Microsoft.SharePoint.WebControls.UnsecuredLayoutsPageBase. This will allow it to be viewed by anonymous users.
I have created a sample page which will do this work for us, it is a page you can drop directly into your layouts folder and call from within your site. All the work is done in inline code much like many of the MOSS layouts pages so it doesn't require a code deployment.
Finally I also placed a secondary text box on the page asking for a pass code in order to perform the change so that if the URL of the page is discovered by an external user then can't easily reset the output cache for a page. You would want to change this pass code in your file to something more appropriate. Find the line which looks like
if(txtPasscode.Text != "supersecretpassword1")
and change the value to something else.
Simply copy the code below into a text file called something like ClearPageFromOutputCache.aspx, drop it into the layouts folder at C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS
You can then access the page using the URL http://www.nameofmypublicsite.com/_layouts/ClearPageFromOutputCache.aspx
Pop in the site relative URL and your chosen pass code and the page should be removed from output cache. Due to how the API works even if you put a non-existent URL in it returns success but there is nothing I can do about this.
<%@ Assembly Name="Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#" Inherits="Microsoft.SharePoint.WebControls.UnsecuredLayoutsPageBase" MasterPageFile="~/_layouts/application.master" EnableViewState="false" EnableViewStateMac="false" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Register TagPrefix="wssawc" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="System.Collections.Generic" %>
<script runat="server">
protected override void OnLoad(EventArgs e)
{
if (IsPostBack)
{
if (txtUrl.Text.Trim() == "")
{
lblResults.Text = "Please enter a valid URL";
return;
}
if(txtUrl.Text.Trim().ToLower().StartsWith("http://"))
{
lblResults.Text = "Please enter a relative URL";
return;
}
if(txtPasscode.Text != "supersecretpassword1")
{
lblResults.Text = "ERROR";
return;
}
try
{
HttpResponse.RemoveOutputCacheItem(txtUrl.Text.Trim());
lblResults.Text = "SUCCESS";
}
catch (Exception ex)
{
lblResults.Text = ex.ToString();
}
}
}
</script>
<asp:Content ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
<sharepoint:encodedliteral runat="server" text="Page Output Cache Clear Tool" encodemethod='HtmlEncode' />
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server">
<sharepoint:formattedstring formattext="Page Output Cache Clear Tool" encodemethod="HtmlEncodeAllowSimpleTextFormatting"
runat="server">
<asp:HyperLink id="onetidListEditTitleLink" runat="server" visible="true"/>
</sharepoint:formattedstring>
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderPageImage" runat="server">
<img src="/_layouts/images/blank.gif" width="1" height="1" alt="">
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderPageDescription" runat="server">
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">
<table cellspacing="0" cellpadding="0" border="0" style="width: 100%; height: 100%" class="propertysheet">
<tr>
<td class="ms-descriptiontext">
<table>
<tr>
<td class="ms-sectionheader">
<h3 class="ms-standardheader">URL</h3>
</td>
</tr>
<tr>
<td class="ms-descriptiontext ms-inputformdescription">
Enter URL of page to clear from output cache, ensure it is a relative URL and NOT an absolute URL</td>
</tr>
</table>
</td>
<td class="ms-authoringcontrols ms-inputformcontrols">
<table>
<tr>
<td>
<asp:TextBox ID="txtUrl" runat="server" CssClass="ms-input" Columns="100" /></td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="ms-descriptiontext">
<table>
<tr>
<td class="ms-sectionheader">
<h3 class="ms-standardheader">Passcode</h3>
</td>
</tr>
<tr>
<td class="ms-descriptiontext ms-inputformdescription">Enter Passcode</td>
</tr>
</table>
</td>
<td class="ms-authoringcontrols ms-inputformcontrols">
<table>
<tr>
<td>
<asp:TextBox ID="txtPasscode" TextMode="Password" runat="server" CssClass="ms-input" Columns="100" /></td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<asp:Label CssClass="ms-formvalidation" Text="" runat="server" ID="lblResults"></asp:Label></td>
</tr>
<tr>
<td class="ms-sectionline" height="2" colspan="5">
<img src="/_layouts/images/blank.gif" width="1" height="1" alt=""></td>
</tr>
<tr>
<td class="ms-spaceBetContentAndButton" colspan="5">
<img src="/_layouts/images/blank.gif" width="1" height="1" alt=""></td>
</tr>
<tr>
<td colspan="5">
<table cellpadding="0" cellspacing="0" width="100%">
<colgroup>
<col width="99%">
<col width="1%">
</colgroup>
<tr>
<td>
</td>
<td nowrap id="align01">
<input id="onetidCreateList" class="ms-ButtonHeightWidth" type="submit" value="<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,multipages_okbutton_text%>' EncodeMethod='HtmlEncode'/>"
accesskey="<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,multipages_okbutton_accesskey%>' EncodeMethod='HtmlEncode'/>">
</td>
</tr>
</table>
</td>
</tr>
<tr height="60">
<td>
</td>
</tr>
</table>
<sharepoint:formdigest runat="server" />
</asp:Content>