Auto-Refresh An ASPX Page Programmatically

I wanted to be able to allow a user of one of my applications to specify an auto-refresh rate for a summary page. There are a whole bunch of ways of doing this – some discussed below – each having their own strengths and weaknesses as techniques. Given my experience, I thought I would share a) another way of doing it and b) some of the challenges I came across when trying to use other techniques.

Introduction

Before I begin I think it would help to show, in a little more detail, what I was trying to accomplish. The screenshot below is from my TechMagic project that essentially allows users a readonly view of a bunch of common tables in Service Desk Express as a series of datagrids housed in an accordian control.

I wanted users to be able to set their own refresh rates that persisted sessions without storing anything in a database and as such chose to make use of cookies. That was the easy bit – automatically refreshing the page became a little more challenging.

Standard Methods of Auto-Refresh

HTTP-EQUIV Method

The HTTP-EQUIV method of auto-refreshing a page is very simple. Essentially between the <head></head> tags of the HTML you simply include a line: <meta http-equiv=”refresh” content=”5″ />. This would cause the page to refresh every 5 seconds. To make this dynamic such that a user can enter a value all we do is change the line slightly to allow access to it programatically:

<meta id="autoRefresh" runat="server" >

Now in the code-behind we can right some code in the Page_Load event that looks something like:

autoRefresh.HttpEquiv = "refresh";
autoRefresh.Content = txtRefreshRate.Text;

JavaScript Method

The JavaScript method is also very easy to implement. We just create a function that puts a timeout on the page:

<head>
<script type="text/javascript" language="javascript">
function refreshPage()
{
window.location = unescape(window.location);
}
function setTimeOut()
{
window.setTimeout(refreshPage, document.getElementById("txtRefreshRate").value * 1000);
}
</script>
</head>

<body onload="setTimeOut()">

A slightly different approach

Both these methods essentially do the same thing and work perfectly well. The problem is that if my users had applied sorting to any of the datagrids or collapsed/expanded different panels, all these settings were forgotten after the page refreshed. I rapidly realised what I ACTUALLY wanted to do was a programatic postback rather than a refresh. So here is how I did it.

Essentially, I used the JavaScript method above but instead of setting the window.location in the refreshPage function, I simply click the Update button that you can see in the screenshot:

function refreshPage()
{
var btn = document.getElementById("btnUpdate");
if (btn) btn.click();
}

This works perfectly but seems, at least to me, a very clumsy approach so as always, I welcome any feedback (positive or negative).

Default Groups when Logging Into Service Desk Express 9.6

Network Associates/BMC have never supported the concept of users having a default group when they log into Magic/Service Desk Express. Judging by the comments in the forums lately I would suggest that this could be a feature for a future release. There were some rather elegant solutions posted in the forums that I think would do rather well, but in the meantime I set about finding a “workaround” to the issue. What I propose to discuss here is an alternative solution that you can implement yourself that will “remember” the user’s last logged on group between browser sessions by storing a cookie on the user’s machine.

PLEASE TAKE A BACKUP COPY OF THE TWO FILES BEFORE MODIFYING THEM AS THIS IS AN UNSUPPORTED HACK!

Also please be careful that when cutting and pasting from this blog to notepad that “” are not accidentally replaced with a different type of quotes.

Storing the Cookie

So the first step is modifying a file that will allow us to store which group the user has logged on as. There are a bunch of files you could do this but I choose options_nailogo.aspx using a little JavaScript. Open options_nailogo.aspx (C:Program FilesBMCService Desk ExpressApplication Server by default) in Notepad or, more preferably, Notepad ++ (an absolutely brilliant editor that I now use for pretty much everything). Near the bottom of the file you will find code that looks like:

<script Language="JavaScript">
//alert(""+strBaseURL);
window.status =  sUserName + "; " + sGroupName;
window.defaultStatus = sUserName + "; " + sGroupName;
document.all("marqWBNotice").trueSpeed=true
</script>
<script language="JavaScript">clmGetText(document)</script>

We are going to insert a little function between these two functions that stores the cookie on the user’s machine such that code looks like:

<script Language="JavaScript">
//alert(""+strBaseURL);
window.status =  sUserName + "; " + sGroupName;
window.defaultStatus = sUserName + "; " + sGroupName;
document.all("marqWBNotice").trueSpeed=true
</script>
<script Language="JavaScript">
var expiry = new Date();
expiry.setTime(exp.getTime() + (1000 * 60 * 60 * 24 * 30));
document.cookie = "SelectedGroup=" + escape(sGroupName) + "; expires=" + expiry.toGMTString() + "; path=/";
</script>
<script language="JavaScript">clmGetText(document)</script>

Save the file.

Retrieving the Cookie

When a user tabs out of the UserName textbox of the Login screen of Service Desk Express a C# function is called that dynamically builds the HTML of the dropdown list based on the list of groups that the user is a member of. So essentially all we are going to do is modify this function to grab the cookie we placed in the function above (if it exists) and use it to set the selected option of the Group downdown list. This function lives in Login.cs. Open Login.cs (C:Program FilesBMCService Desk ExpressApplication Serverincludes by default) in any text editor and replace the function GetUserGroups with the function below:

string GetUserGroups(string sUsrName)
{
string strGRPName, strGRPSeq, strOutPut;
strOutPut = "";
string strDefaultGRPName = "";
HttpCookie cookie = Request.Cookies["SelectedGroup"];
if (null != cookie)
{
strDefaultGRPName = cookie.Value.ToString();
strDefaultGRPName = strDefaultGRPName.Replace("%20", " ");
}
if (MetaData != null)
{
System.Diagnostics.Trace.WriteLine("[Login] Metadata available.");
NAMMETADATALib.IMUser objUser = (MetaData.Users as NAMMETADATALib.IMUsers).GetUserByName(sUsrName) as NAMMETADATALib.IMUser;
if (objUser != null)
{
for (int i = 0; i < objUser.GroupCount; i++)
{
NAMMETADATALib.IMGroup objGroup = objUser.GetGroupByIndex(i) as NAMMETADATALib.IMGroup;
if (objGroup.IsActive == true)
{
strGRPName = objGroup.name;
strGRPSeq = objGroup.Sequence.ToString();
if (strDefaultGRPName != "")
{
if (strGRPName == strDefaultGRPName)
{
strOutPut = strOutPut + "<OPTION ID=" + strGRPSeq + " SELECTED="True">" + strGRPName + "</OPTION>";
}
else
{
strOutPut = strOutPut + "<OPTION ID=" + strGRPSeq + ">" + strGRPName + "</OPTION>";
}
}
else
{
strOutPut = strOutPut + "<OPTION ID=" + strGRPSeq + ">" + strGRPName + "</OPTION>";
}
}
}
}
else
{
strOutPut = "NOTVALIDUSER";
}
}
else
{
System.Collections.SortedList oUsers=null;
try
{
oUsers = (System.Collections.SortedList)FeatureManager.GetUserGroups(sUsrName);
}
catch(Exception e)
{
string strResponse="<DATA>";
strResponse=strResponse+ "<ERROR>"+ e.Message +"</ERROR>";
strResponse=strResponse+"</DATA>";
strOutPut=strResponse;
return strOutPut;
}
if (oUsers != null)
{
if (oUsers.Count == 0)
{
strOutPut = "NOTVALIDUSER";
}
for (int i = 0; i < oUsers.Count; i++)
{
strGRPSeq = oUsers.GetKey(i).ToString();
strGRPName = oUsers.GetByIndex(i).ToString();
if (strDefaultGRPName != "")
{
if (strGRPName == strDefaultGRPName)
{
strOutPut = strOutPut + "<OPTION ID=" + strGRPSeq + " SELECTED="True">" + strGRPName + "</OPTION>";
}
else
{
strOutPut = strOutPut + "<OPTION ID=" + strGRPSeq + ">" + strGRPName + "</OPTION>";
}
}
else
{
strOutPut = strOutPut + "<OPTION ID=" + strGRPSeq + ">" + strGRPName + "</OPTION>";
}
}
}
}
return strOutPut;
}

Save the file and that’s it. You may need to clear your browser’s cache and it is probably worth an IISRESET as well.

As always, hope this helps, and any feedback (positive or negative) is always appreciated.