Anyway, the issue is that I get the dreaded Javascript error messages if I use my own HttpModule. Unfortunately, I need to use it because it implements (using a mechanism proven to work reliably even with these errors) the ability to detect if the user hit the page refresh button. It is critical that this detection exists in my application because of other mechanisms we need to use. Anyway, below if the full code of my HttpModule and related classes:
public class RefreshAction
{
// ***********************************************************
// Constants
public const string LastRefreshTicketEntry = "__LASTREFRESHTICKET";
public const string CurrentRefreshTicketEntry = "__CURRENTREFRESHTICKET";
public const string PageRefreshEntry = "IsPageRefresh";
// ***********************************************************
// ***********************************************************
// Manage to check if the F5 button has been pressed
public static void Check(HttpContext ctx)
{
// Initialize the ticket slot
EnsureRefreshTicket(ctx);
// Read the last ticket served in the session (from Session)
int lastTicket = GetLastRefreshTicket(ctx);
// Read the ticket of the current request (from a hidden field)
int thisTicket = GetCurrentRefreshTicket(ctx);
// Compare tickets
if (thisTicket > lastTicket ||
(thisTicket == lastTicket && thisTicket == 0))
{
UpdateLastRefreshTicket(ctx, thisTicket);
ctx.Items[PageRefreshEntry] =
false;
}
else
{
ctx.Items[PageRefreshEntry] =
true;
}
}
// ***********************************************************
// ***********************************************************
// Ensure that the slot for the last ticket served isn't null
private static void EnsureRefreshTicket(HttpContext ctx)
{
// Initialize the session slots for the page (Ticket) and the module (LastTicketServed)
if (ctx.Session[LastRefreshTicketEntry] == null)
ctx.Session[LastRefreshTicketEntry] = 0;
}
// ***********************************************************
// ***********************************************************
// Return the ticket of the last request in the session
private static int GetLastRefreshTicket(HttpContext ctx)
{
// Extract and return the last ticket
return Convert.ToInt32(ctx.Session[LastRefreshTicketEntry]);
}
// ***********************************************************
// ***********************************************************
// Return the ticket of the last request in the session
private static int GetCurrentRefreshTicket(HttpContext ctx)
{
return Convert.ToInt32(ctx.Request[CurrentRefreshTicketEntry]);
}
// ***********************************************************
// ***********************************************************
// Return the ticket of the last request in the session
private static void UpdateLastRefreshTicket(HttpContext ctx, int ticket)
{
ctx.Session[LastRefreshTicketEntry] = ticket;
}
// ***********************************************************
}
public class RefreshModule : IHttpModule
{
// ***********************************************************
// IHttpModule::Init
public void Init(HttpApplication app)
{
// Register for pipeline events
app.AcquireRequestState +=
new EventHandler(this.OnAcquireRequestState);
}
// ***********************************************************
// ***********************************************************
// IHttpModule::Dispose
public void Dispose()
{
}
// ***********************************************************
// ***********************************************************
// Determine if a F5 or back/fwd action is in course
private void OnAcquireRequestState(object sender, EventArgs e)
{
// Get access to the HTTP context
HttpApplication app = (HttpApplication)sender;
HttpContext ctx = app.Context;
// Check F5 action
RefreshAction.Check(ctx);
return;
}
// ***********************************************************
}
This is then used by a custom Page class that my app inherits from that allows me to check if this is a page refresh or not. The relevant methods from my Page class are below:
// **************************************************************
// Indicates if the page is being viewed in response to F5 hit
public bool IsPageRefresh
{
get
{
object o = HttpContext.Current.Items[RefreshAction.PageRefreshEntry];
if (o == null)
return false;
return (bool)o;
}
}
// **************************************************************
// **************************************************************
// Increase the internal counter used to generate refresh tickets
public void TrackRefreshState()
{
InitRefreshState();
int ticket = Convert.ToInt32(Session[RefreshTicketCounter]) + 1;
Session[RefreshTicketCounter] = ticket;
}
// **************************************************************
#region
Private Members
// **************************************************************
// Create the hidden field to store the current request ticket
private void SaveRefreshState()
{
int ticket = Convert.ToInt32(Session[RefreshTicketCounter]) + 1;
RegisterHiddenField(
RefreshAction.CurrentRefreshTicketEntry, ticket.ToString());
}
// **************************************************************
// **************************************************************
// Ensure that the ticket counter is initialized
private void InitRefreshState()
{
if (Session[RefreshTicketCounter] == null)
Session[RefreshTicketCounter] = 0;
}
// **************************************************************
// **************************************************************
// Handle the PreRender event
private void RefreshPage_PreRender(object sender, EventArgs e)
{
SaveRefreshState();
}
// **************************************************************
If there is anything obvious in the above that would interfere with RadAjax, could you suggest how to avoid breaking it? I do understand that I may be able to resolve the problem by having the application(s) reference the scripts and set UseEmbedded Scripts="False", but these HttpModule and Page classes are actually being used as our base classes on several applications. It becomes somewhat less than ideal from a software release distribution standpoint if we have to modify our page markup to reference the right version path of the RadControls for several applications every time we upgrade to a new release of RadControls. It also tends to make the applications know more about the underlying controls than I would prefer, since normally it wouldn;t be typical to have to add the script references on the pages using them.
Thanks,
-Ed