Scott Cate Weblog 

scott.cate@myKB.com
http://scottcate.myKB.com



Scott Cate KB > ASP.NET Code Samples - Findings > ASP.NET Class Start Over
Search the Knowledge Base
 
Start Search in the Following Category
Date Modified
Thursday, February 05, 2004
HttpContext.Cache Viewer (With DataSet Support)

Aw, the HttpContext.Cache. Most of the items I place in the Cache are named with GUID's so it's not very helpful to loop through and print out the Cache Item Name. I've built this handy ASPX page that gives a nice little view of the Cache in human readable form. All the Datasets, are displayed, including the DataTables. now keep in mind, that I'm not worried about the graphic design, or the looks here, I just wanted to make something work. I did add a little javascript to expand/collapse the items since they tend to be rather large.

I'm happy to answer questions, and I'm eager for advice, on a better way, faster way, or just general feedback on the code.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<script language="javascript">
<!--
function OpenOrCloseSpan(spanTag)
{
var st = document.getElementById( spanTag );
if ( st.style.display == 'none' )
st.style.display = '';
else
st.style.display = 'none';
}
// -->
</script>
<HTML>
<HEAD>
<title>Display Cache Keys And Values</title>
</HEAD>
<body>
<a href="DisplayCacheKeyValues.aspx">Refresh Page</a>
<form id="Form1" method="post" runat="server">
<asp:PlaceHolder ID="phTable" Runat="server" />
</form>
</body>
</HTML>
protected System.Web.UI.WebControls.PlaceHolder phTable;


private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
GetAndDisplayCacheItems();
}
else
{
//These have to be bound to fire the event. This method
//Bind the link buttons, but without the rest of the over head
CreateAndBindRemoveButtons();
}
}

private void GetAndDisplayCacheItems()
{
//this stringbuilder gets used throughout the method as needed.
StringBuilder sb = new StringBuilder();

//Grab the context item, for reference so it has local scope to
//save having to get walk back and get the Context item
HttpContext ctx = HttpContext.Current;
IDictionaryEnumerator d = ctx.Cache.GetEnumerator();
while(d.MoveNext())
{
// Create HTML table for display of each item in cache
HtmlTable t = new HtmlTable();
//Set General Table Properties
t.BorderColor = "FF0000";
t.CellPadding = 10;
t.CellSpacing = 0;
t.Border = 1;

HtmlTableRow r = new HtmlTableRow();
HtmlTableCell CacheKeyTableCell = new HtmlTableCell();
CacheKeyTableCell.VAlign = "top";

//Clear the stringbuilder and add the CachItem Type and value
sb.Length = 0;
sb.Append("<B>Cache Item Type: </B>");
sb.Append(ctx.Cache[d.Key.ToString()].GetType().ToString());
sb.Append("<BR /><B>Value: </B><BR />");
sb.Append(Server.HtmlEncode(d.Value.ToString()));

//Add the Item Type
CacheKeyTableCell.Controls.Add(new LiteralControl(sb.ToString()));
r.Cells.Add(CacheKeyTableCell);

HtmlTableCell CacheValueTableCell = new HtmlTableCell();
switch(d.Value.ToString())
{
//This is the fun code, that turns dataset tables,
//into HTML Tables
case "System.Data.DataSet" :
//Coutner to Create a label
int tblCounter = 0;
//Create a new dataset to be used as a copy of the cached dataset
//We do this, becuase some of the values get manipulated and we
//don't want to chagne the actual values.
DataSet ds = new DataSet();
//Get copy of dataset from Cache
ds = ((DataSet)ctx.Cache[d.Key.ToString()]).Copy();
//Iterate throguht the tables in the dataset
foreach(DataTable dt in ds.Tables)
{
//Set flag to see if the table has rows.
//We won't add empty tables to the view
bool rowsProcessed = false;
foreach(DataRow dr in dt.Rows )
{
//Found rows, set flag to true
rowsProcessed = true;
//loop through each colomn int he DataRow and convert
//any text, to HTML text. A lot of cached data, is data that
//gets rendered as XML, or HTML, so this makes the data human
//readable. This is the reason for working with a copy of the
//dataset, and not the real cached item.
for(int x = 0; x < dr.ItemArray.GetLength(0); x++)
{
//This is my sloppy way to catch nulls, and any other
//conversion errors.
try
{
string columnData = Server.HtmlEncode(dr[x].ToString());
dr[x] = columnData;
}
catch {}
}
}
//Add populated tables to ValueTableCell, via
//new datagrid.AutoGenerateColumns
if(rowsProcessed)
{
//Add Seperation bar between Tables
if(tblCounter > 0)
{
CacheValueTableCell.Controls.Add(new LiteralControl("<HR>"));
}
DataGrid dg = new DataGrid();
dg.GridLines = GridLines.Both;
dg.AutoGenerateColumns = true;
dg.BorderColor = Color.Black;
dg.BorderWidth = Unit.Pixel(2);
dg.DataSource = dt;
dg.DataBind();
//Set some styles on the columns for readability
foreach(DataGridColumn c in dg.Columns)
{
c.ItemStyle.HorizontalAlign = HorizontalAlign.Left;
c.ItemStyle.VerticalAlign = VerticalAlign.Top;
}
//Add a Table Counter Label
sb.Length = 0;
sb.Append("DataTable ");
sb.Append(tblCounter.ToString());
sb.Append("<BR />");
CacheValueTableCell.Controls.Add(new LiteralControl(sb.ToString()));
CacheValueTableCell.Controls.Add(dg);
}
tblCounter++;
}
r.Cells.Add(CacheValueTableCell);
break;
default :
break;
}
//Add the row to the HTML table
t.Rows.Add(r);

//Start <P> Tag
phTable.Controls.Add(new LiteralControl("<P>"));

//Create and add Remove Link Button
phTable.Controls.Add(CreateRemoveLinkButton(d.Key.ToString()));

//Add a spacer between the remove link button and the open/close javascript
phTable.Controls.Add(new LiteralControl("&nbsp;"));

//Create and add the anchor tag to open/close javascript
HtmlAnchor a = new HtmlAnchor();
a.HRef= "Javascript:OpenOrCloseSpan('Span_" + d.Key.ToString() + "')";
a.Controls.Add(new LiteralControl("Open/Close"));
phTable.Controls.Add(a);

//Create and add the Name of the Cache Item (preeceded with a space)
StringBuilder CacheItemDisplayName = new StringBuilder();
CacheItemDisplayName.Append("&nbsp;");
CacheItemDisplayName.Append(d.Key.ToString());

//Add the Open Span Tag and ID for javascript to open and close
CacheItemDisplayName.Append("<span id=\"span_");
CacheItemDisplayName.Append(d.Key.ToString());
CacheItemDisplayName.Append("\" style=\"Display: None\">");
phTable.Controls.Add(new LiteralControl(CacheItemDisplayName.ToString()));

//Add the data table to the placeholder
phTable.Controls.Add(t);
//Add the closing Span and P tags.
phTable.Controls.Add(new LiteralControl("</span></P>"));
}
}

private LinkButton CreateRemoveLinkButton(string buttonID)
{
LinkButton RemoveLinkButton = new LinkButton();
RemoveLinkButton.Text = "Remove";
//Set the ID of the LinkButton to the Cache Key Name.
//This is going to be used in the eventhandler, to remove item from cache
RemoveLinkButton.ID = buttonID;
//Wire up event
RemoveLinkButton.Click += new EventHandler(RemoveLinkButton_Click);
return RemoveLinkButton;
}

private void CreateAndBindRemoveButtons()
{
HttpContext ctx = HttpContext.Current;
IDictionaryEnumerator d = ctx.Cache.GetEnumerator();
while(d.MoveNext())
{
phTable.Controls.Add(CreateRemoveLinkButton(d.Key.ToString()));
}
}

private void RemoveLinkButton_Click(object sender, EventArgs e)
{
HttpContext ctx = HttpContext.Current;
//Cast sender as LinkButton and Check if still in cache
if(ctx.Cache[((LinkButton)sender).ID] != null)
{
//Remove item from Cache
ctx.Cache.Remove(((LinkButton)sender).ID);
}
phTable.Controls.Clear();
GetAndDisplayCacheItems();
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion


All rights reserved. All details are the personal opinion of Scott Cate.
All trademarks referenced are the property of their respective owners.
Scott Cate is a lead programmer for www.myKB.com and
owner of The Arizona .NET User Group and an all around nice guy ;)


Knowledge Base Software - myKB.com

 

Cameron Cate Pictures
Cameron Cate Pix

Site Navigation

Home
Knowledge Base
Wiki Discussions
Photo Album

Sites I Own & Run


Easy Search ASP.NET
mykb.com knowledge base software logo
myKB.com
Knowledgebase Software

KBAlertz.com
Arizona .NET user Group
Group Leader

Affiliations


ASP.NET MVP
2004
2005
2006
2007
2008
2009


Blog Sites I Read

Brady Gaster
Rob Howard
G. Andrew  Duthie
Robert McLaws
Alex Lowe

World of Scott.Net

Scott Guthrie
  -  Father of ASP.NET

Scott Watermasyk
  - .Text (Weblog)

Scott Sargent
Scott Mitchell
ScottG.net
Scott Bellware
Scott Forsyth
Scott Hanselman
Scott Cate

Favorite Books


ASP.NET Cookbook


First Looks @ ASP.NET 2.0