Let me know if you find a definitive solution...
Finally got it to work.
I used as my basic code the code from
http://jarednevans.typepad.com/technoblog/2005/01/jareds_techno_b.html.
The problem with this code is it doesn't take into account the Initial page
load being refreshed, which may not be a problem most of the time. But if
you do any database processing, setting session variables etc. - this could
be a problem.
What I added was the setting of a session variable to the URL and when I
enter the page, if the page is NOT a Post Backed page I compare the current
URL with what is in the Session variable. If they don't match or the
Session Variable is not there, then this is not a refresh. If it is there,
then the page was either refreshed or they just reentered the URL in the
Browsers Address line (really the same thing).
I also found that SVS (SaveViewState) is executed twice if you have tracing
on (trace="true"). You'll notice the first SVS is done between events (at
least the events that display on the trace page). I assume this one is the
being executed by Trace in some way because right after that the
SaveViewState is executed. If trace is off, you only get the SVS.
Also, the trace statement is the only thing that is in my SVS call. So
something is calling my SVS event other than the Page SVS and there are no
controls on the page.
aspx.page Begin Init
aspx.page End Init 0.000079 0.000079
aspx.page Begin PreRender 0.000116 0.000037
aspx.page End PreRender 0.000165 0.000049
Inside refresh.cs at SaveViewState 0.000880 0.000715
aspx.page Begin SaveViewState 0.001932 0.001053
Inside refresh.cs at SaveViewState 0.002330 0.000398
aspx.page End SaveViewState 0.002384 0.000054
aspx.page Begin Render 0.002411 0.000027
aspx.page End Render 0.137321 0.134909
So what I do set a variable, _firstTime, that I set to false in the 1st SVS
so that the 2nd SVS will execute normally but won't set anything.
To make this work for only specific pages, you need to add
Inherits="MyFunctions.Page" to the Page tag on the page:
<%@ Page Language="VB" trace="true" debug="true" ContentType="text/html"
ResponseEncoding="iso-8859-1" Inherits="MyFunctions.Page" %>
or if you want this to work for every page I believe you can set it in your
Web.Config file:
<pages Inherits="MyFunctions.Page" />
The one problem I have not been able figure out (if you are only doing this
for specific pages) is when you load a page (which would set the Session
variable) then go directly another set of pages not using this procedure.
If you then go back to the 1st page, it will set the session variable set
and think this is a refresh, when in fact it isn't.
Here is the actual code (in c# as that is what I created this in, but then I
converted it to vb for here).
***************************************************************************
using System;
using System.IO;
using System.Web;
using System.Web.UI;
using System.Web.SessionState;
namespace MyFunctions
{
// This program deals with 2 situations of refresh.
// Initial load of a page
// Checks to see if this is a PostBack.
// If not - Checks to see if Session("__LASTPAGEPROCESSED") matches the
current URL.
// If it does, the page has either been refreshed or re-entered in the
address line of Browser
// PostBack
// Checks to see if _refreshState that is stored in the ViewState matches
Session["__ISREFRESH"].
// if it does, we have a refresh. This is because we set the Session
variable and put the reverse
// value in the viewstate. If we refresh the page we get the old
viewstate back and the old viewstate
// value should match our new Session value. Remember we keep reversing
the values.
public class Page : System.Web.UI.Page
{
private bool _refreshState;
private bool _isRefresh;
// This variable is only important to signify whether SaveViewState is
executing for a second time
// During the same Page Life Cycle. Have only seen this when you have
tracing on (Trace="true")
private bool _firstTime = true;
public bool IsRefresh
{
get
{
if (!IsPostBack)
{
if ((Session["__INITIALREFRESHPAGE"] != null) &&
((string)Session["__INITIALREFRESHPAGE"] ==
HttpContext.Current.Request.Url.ToString()))
{
// Need to set this here as this is a refresh or was re-executed from
the URL line.
// In either case, the results are the same.
_isRefresh = true;
}
}
return _isRefresh;
}
}
public bool IsFirstTime
{
get
{
return _firstTime;
}
set
{
_firstTime = value;
}
}
protected override void LoadViewState(object savedState)
{
object[] allStates = (object[]) savedState;
base.LoadViewState(allStates[0]);
_refreshState = (bool) allStates[1];
_isRefresh = _refreshState == (bool) Session["__ISREFRESH"];
Session.Remove("__INITIALREFRESHPAGE"); // Only there to test initial
page load refresh
}
protected override object SaveViewState()
{
object[] allStates = new object[2];
allStates[0] = base.SaveViewState();
// This test is mainly when trace="true". SaveViewState will execute twice
and we only need to process this once
if (_firstTime)
{
// This only happens on the initial load of a page where there is no
LoadViewState
if (!IsPostBack)
{
Session["__INITIALREFRESHPAGE"] =
HttpContext.Current.Request.Url.ToString();
}
Session["__ISREFRESH"] = _refreshState;
allStates[1] = !_refreshState;
}
else
{
// We already reversed _refresh states. To do it again would put it back
the way it was.
// Need to store the _refreshState anyway as we need to return the
ViewState.
allStates[1] = !_refreshState;
}
_firstTime = false;
return allStates;
}
}
}
****************************************************************************
Here is the converted VB code (but I haven't tested it)
*****************************************************************
Imports System
Imports System.IO
Imports System.Web
Imports System.Web.UI
Imports System.Web.SessionState
' This program deals with 2 situations of refresh.
' Initial load of a page
' Checks to see if this is a PostBack.
' If not - Checks to see if Session("__LASTPAGEPROCESSED") matches the
current URL.
' If it does, the page has either been refreshed or re-entered in the
address line of Browser
' PostBack
' Checks to see if _refreshState that is stored in the ViewState matches
Session["__ISREFRESH"].
' if it does, we have a refresh. This is because we set the Session
variable and put the reverse
' value in the viewstate. If we refresh the page we get the old viewstate
back and the old viewstate
' value should match our new Session value. Remember we keep reversing
the values.
Public Class Page
Inherits System.Web.UI.Page
Private _refreshState As Boolean
Private _isRefresh As Boolean
' This variable is only important to signify whether SaveViewState is
executing for a second time
' During the same Page Life Cycle. Have only seen this when you have
tracing on (Trace="true")
Private _firstTime As Boolean = True
Public ReadOnly Property IsRefresh() As Boolean
Get
If Not IsPostBack Then
If Not (Session("__INITIALREFRESHPAGE") Is Nothing) And
CStr(Session("__INITIALREFRESHPAGE")) =
HttpContext.Current.Request.Url.ToString() Then
' Need to set this here as this is a refresh or was
re-executed from the URL line.
' In either case, the results are the same.
_isRefresh = True
End If
End If
Return _isRefresh
End Get
End Property
Public Property IsFirstTime() As Boolean
Get
Return _firstTime
End Get
Set
_firstTime = value
End Set
End Property
Protected Overrides Sub LoadViewState(savedState As Object)
Dim allStates As Object() = CType(savedState, Object())
MyBase.LoadViewState(allStates(0))
_refreshState = CBool(allStates(1))
_isRefresh = _refreshState = CBool(Session("__ISREFRESH"))
Session.Remove("__INITIALREFRESHPAGE") ' Only there to test initial
page load refresh
End Sub 'LoadViewState
Protected Overrides Function SaveViewState() As Object
Dim allStates(2) As Object
allStates(0) = MyBase.SaveViewState()
' This test is mainly when trace="true". SaveViewState will execute
twice and we only need to process this once
If _firstTime Then
' This only happens on the initial load of a page where there is
no LoadViewState
If Not IsPostBack Then
Session("__INITIALREFRESHPAGE") =
HttpContext.Current.Request.Url.ToString()
End If
Session("__ISREFRESH") = _refreshState
allStates(1) = Not _refreshState
Else
' We already reversed _refresh states. To do it again would put
it back the way it was.
' Need to store the _refreshState anyway as we need to return the
ViewState.
allStates(1) = Not _refreshState
End If
_firstTime = False
Return allStates
End Function 'SaveViewState
End Class 'Page
*****************************************************************************
In your code, you only have to check the property:
if IsRefresh...
Seems to work OK, except for the one problem I stated.
Someone mentioned a problem with the backbutton in the other program, but I
am not dealing with that here - just a refresh.
Tom
Tommaso
tshad ha scritto: