SaveViewState executing twice

T

tshad

I thought I understood how the SaveViewState is working and was trying to
use this (as per some code I found) to detect refreshes. It seemed to be
working but I found that the SaveViewState was executing twice on load of
page and can't figure out why.

I was writing out to a text file in the SaveViewState event and it was
writing it twice everytime a page was loaded (whether on an initial load of
the page or Postback).

I took out the writes to the text file and added the "trace.warn" to see
where it was happening.

The thing I noticed is that the first SaveViewState is executing outside all
the Events.

It is executing after the End of the PreRender and before the Start of the
normal SaveViewState.

aspx.page Begin Init
aspx.page End Init 0.000072 0.000072
aspx.page Begin PreRender 0.000111 0.000039
aspx.page End PreRender 0.000160 0.000049
Inside refresh.cs at SaveViewState 0.000884 0.000725
aspx.page Begin SaveViewState 0.001542 0.000657
Inside refresh.cs at SaveViewState 0.001885 0.000344
aspx.page End SaveViewState 0.001929 0.000044
aspx.page Begin Render 0.001956 0.000027
aspx.page End Render 0.111191 0.109235

Just to make sure my code was working correctly, I rewrote the class to do
nothing except what is done normally.

namespace MyFunctions
{
public class Page : System.Web.UI.Page
{
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}

protected override object SaveViewState()
{
Trace.Warn("Inside refresh.cs at SaveViewState");
return base.SaveViewState();
}
}
}



I am still getting the same results.

It calls the SaveViewState twice. This is not what the documentations say
(at least not that I can find).

Am I missing something?

Thanks,

Tom
 
S

Scott M.

First, I would try setting breakpoints and stepping through your code line
by line to verify your assertion that SVS is firing twice during one page
request, rather than assume this is the case by looking at the trace. The
trace is not necessarially an event by event listing of what happend during
the page request. It's more of a stage by stage description.

Second, I wouldn't be adding any code to the LVS or the SVS event handlers
unless that code has to do with the loading or saving of viewstate. Writing
out to a text file doesn't need to be done here. Use Page_Load instead.
 
T

tshad

Scott M. said:
First, I would try setting breakpoints and stepping through your code line
by line to verify your assertion that SVS is firing twice during one page
request, rather than assume this is the case by looking at the trace. The
trace is not necessarially an event by event listing of what happend
during the page request. It's more of a stage by stage description.

I only did that to check if the code was working correctly.
Second, I wouldn't be adding any code to the LVS or the SVS event handlers
unless that code has to do with the loading or saving of viewstate.
Writing out to a text file doesn't need to be done here. Use Page_Load
instead.

The actual code was loading data into the viewstate.

I was writing into my textfile only to see what was happening.

What I found was that the SaveViewState was being fired twice because on the
first Session(ISREFRESH) was equal to nothing and on the second time it was
fired it would be "false"

At start of SaveViewState - _refreshState = False Session(ISREFRESH) =
isRefresh = False
At End of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False

At start of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False
At End of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False


********************************************************************************************
protected override object SaveViewState()
{
bool _isrefresh = false;
string _tname = "__Ticket";

FileStream fs = new
FileStream("c:\\inetpub\\wwwroot\\staffingworkshop\\uploads\\tfsRefresh.txt",
FileMode.Append, FileAccess.Write);
StreamWriter s = new StreamWriter(fs);
s.BaseStream.Seek(0,SeekOrigin.End);
s.WriteLine(" ");
s.WriteLine("C# Version");
s.WriteLine("At start of SaveViewState - _refreshState = " + _refreshState +
" Session(ISREFRESH) = " + Session["__ISREFRESH"] + " isRefresh = " +
_isRefresh);
Session["__ISREFRESH"] = _refreshState;
object[] allStates = new object[2];
allStates[0] = base.SaveViewState();
allStates[1] = !_refreshState;
s.WriteLine("At End of SaveViewState - _refreshState = " + _refreshState + "
Session(ISREFRESH) = " + Session["__ISREFRESH"] + " isRefresh = " +
_isRefresh);
s.Close();
return allStates;
}
}
**********************************************************************************

The thing is this didn't use to be the case. I looked at my old text file
and it was only firing once. Something is causing it to fire twice now. I
started stripping out code to see if something I was doing was causing the
problem, but when I got it down to the bare minimum, it was still doing it.

This was driving me crazy as there didn't seem to be any rhyme or reason for
this happening. As you can see from below there is nothing there. So what
could be causing it. I tried restarting my machine to see if there was a
problem there, but that didn't do it.

Tom
 
S

Scott M.

Your code is using sessions for storage and retrieval of data, but you are
talking about viewstate. Session data and ViewState data are not the same
thing.

Also, you still seem to be saying that SVS is firing twice because of an
assumption, not because of a fact. Take all your code out of SVS and just
place a dummy line of code (create a variable and assign it a value). Set a
breakpoint on this line and execute your code (with debugging) and step
(line by line) through the code. I really think under this scenario, you
will see SVS fires only once per page request.

Lastly, even if you wish to add to ViewState, I still wouldn't do it from
within the SVS or LVS events. Do it from Page_Load and use IsPostBack if
needed.

I belive you are not getting the results you want because of the code you
wrote and not because the SVS event is working incorrectly.



tshad said:
Scott M. said:
First, I would try setting breakpoints and stepping through your code
line by line to verify your assertion that SVS is firing twice during one
page request, rather than assume this is the case by looking at the
trace. The trace is not necessarially an event by event listing of what
happend during the page request. It's more of a stage by stage
description.

I only did that to check if the code was working correctly.
Second, I wouldn't be adding any code to the LVS or the SVS event
handlers unless that code has to do with the loading or saving of
viewstate. Writing out to a text file doesn't need to be done here. Use
Page_Load instead.

The actual code was loading data into the viewstate.

I was writing into my textfile only to see what was happening.

What I found was that the SaveViewState was being fired twice because on
the first Session(ISREFRESH) was equal to nothing and on the second time
it was fired it would be "false"

At start of SaveViewState - _refreshState = False Session(ISREFRESH) =
isRefresh = False
At End of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False

At start of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False
At End of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False


********************************************************************************************
protected override object SaveViewState()
{
bool _isrefresh = false;
string _tname = "__Ticket";

FileStream fs = new
FileStream("c:\\inetpub\\wwwroot\\staffingworkshop\\uploads\\tfsRefresh.txt",
FileMode.Append, FileAccess.Write);
StreamWriter s = new StreamWriter(fs);
s.BaseStream.Seek(0,SeekOrigin.End);
s.WriteLine(" ");
s.WriteLine("C# Version");
s.WriteLine("At start of SaveViewState - _refreshState = " + _refreshState
+ " Session(ISREFRESH) = " + Session["__ISREFRESH"] + " isRefresh = "
+ _isRefresh);
Session["__ISREFRESH"] = _refreshState;
object[] allStates = new object[2];
allStates[0] = base.SaveViewState();
allStates[1] = !_refreshState;
s.WriteLine("At End of SaveViewState - _refreshState = " + _refreshState +
" Session(ISREFRESH) = " + Session["__ISREFRESH"] + " isRefresh = " +
_isRefresh);
s.Close();
return allStates;
}
}
**********************************************************************************

The thing is this didn't use to be the case. I looked at my old text file
and it was only firing once. Something is causing it to fire twice now.
I started stripping out code to see if something I was doing was causing
the problem, but when I got it down to the bare minimum, it was still
doing it.

This was driving me crazy as there didn't seem to be any rhyme or reason
for this happening. As you can see from below there is nothing there. So
what could be causing it. I tried restarting my machine to see if there
was a problem there, but that didn't do it.

Tom
 
T

tshad

Scott M. said:
Your code is using sessions for storage and retrieval of data, but you are
talking about viewstate. Session data and ViewState data are not the same
thing.

Also, you still seem to be saying that SVS is firing twice because of an
assumption, not because of a fact. Take all your code out of SVS and just
place a dummy line of code (create a variable and assign it a value). Set
a breakpoint on this line and execute your code (with debugging) and step
(line by line) through the code. I really think under this scenario, you
will see SVS fires only once per page request.

Lastly, even if you wish to add to ViewState, I still wouldn't do it from
within the SVS or LVS events. Do it from Page_Load and use IsPostBack if
needed.

I got this from:

http://jarednevans.typepad.com/technoblog/2005/01/jareds_techno_b.html

It does seem to work fine for Pages that have already been posted back, but
doesn't work for initial pages that are being refreshed. This is because
the LoadViewState doesn't fire. I was looking at using a session variable
(similar to Dino Espositos solution that is mentioned in the above article)
is some way to handle this.

What is your reason for not doing it this way? Is it that you don't like
the base Page Class setup? I want to set this up so that all my using it
and this seemed like a pretty good place to do this (except for the
LoadViewState problem - which I am looking at).
I belive you are not getting the results you want because of the code you
wrote and not because the SVS event is working incorrectly.

You were right. It wasn't what I wrote but that I had the trace set to true.
This causes the SVS to fire a second time (I assume the event that fires
between the normal page events is from this).

This is why it was confusing. It would work fine then all of a sudden it
wouldn't.

Using the following:
*************************************
using System;
using System.Web;
using System.Web.SessionState;

namespace MyFunctions
{
public class Page : System.Web.UI.Page
{
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}

protected override object SaveViewState()
{
return base.SaveViewState();
}
}
}
**********************************************

Works fine if trace="false", but fires a 2nd time if trace="true".

Do you know why it does that?

Thanks,

Tom
tshad said:
Scott M. said:
First, I would try setting breakpoints and stepping through your code
line by line to verify your assertion that SVS is firing twice during
one page request, rather than assume this is the case by looking at the
trace. The trace is not necessarially an event by event listing of what
happend during the page request. It's more of a stage by stage
description.

I only did that to check if the code was working correctly.
Second, I wouldn't be adding any code to the LVS or the SVS event
handlers unless that code has to do with the loading or saving of
viewstate. Writing out to a text file doesn't need to be done here. Use
Page_Load instead.

The actual code was loading data into the viewstate.

I was writing into my textfile only to see what was happening.

What I found was that the SaveViewState was being fired twice because on
the first Session(ISREFRESH) was equal to nothing and on the second time
it was fired it would be "false"

At start of SaveViewState - _refreshState = False Session(ISREFRESH) =
isRefresh = False
At End of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False

At start of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False
At End of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False


********************************************************************************************
protected override object SaveViewState()
{
bool _isrefresh = false;
string _tname = "__Ticket";

FileStream fs = new
FileStream("c:\\inetpub\\wwwroot\\staffingworkshop\\uploads\\tfsRefresh.txt",
FileMode.Append, FileAccess.Write);
StreamWriter s = new StreamWriter(fs);
s.BaseStream.Seek(0,SeekOrigin.End);
s.WriteLine(" ");
s.WriteLine("C# Version");
s.WriteLine("At start of SaveViewState - _refreshState = " +
_refreshState + " Session(ISREFRESH) = " + Session["__ISREFRESH"] + "
isRefresh = " + _isRefresh);
Session["__ISREFRESH"] = _refreshState;
object[] allStates = new object[2];
allStates[0] = base.SaveViewState();
allStates[1] = !_refreshState;
s.WriteLine("At End of SaveViewState - _refreshState = " + _refreshState
+ " Session(ISREFRESH) = " + Session["__ISREFRESH"] + " isRefresh = " +
_isRefresh);
s.Close();
return allStates;
}
}
**********************************************************************************

The thing is this didn't use to be the case. I looked at my old text
file and it was only firing once. Something is causing it to fire twice
now. I started stripping out code to see if something I was doing was
causing the problem, but when I got it down to the bare minimum, it was
still doing it.

This was driving me crazy as there didn't seem to be any rhyme or reason
for this happening. As you can see from below there is nothing there.
So what could be causing it. I tried restarting my machine to see if
there was a problem there, but that didn't do it.

Tom
I thought I understood how the SaveViewState is working and was trying
to use this (as per some code I found) to detect refreshes. It seemed
to be working but I found that the SaveViewState was executing twice on
load of page and can't figure out why.

I was writing out to a text file in the SaveViewState event and it was
writing it twice everytime a page was loaded (whether on an initial
load of the page or Postback).

I took out the writes to the text file and added the "trace.warn" to
see where it was happening.

The thing I noticed is that the first SaveViewState is executing
outside all the Events.

It is executing after the End of the PreRender and before the Start of
the normal SaveViewState.

aspx.page Begin Init
aspx.page End Init 0.000072 0.000072
aspx.page Begin PreRender 0.000111 0.000039
aspx.page End PreRender 0.000160 0.000049
Inside refresh.cs at SaveViewState 0.000884 0.000725
aspx.page Begin SaveViewState 0.001542 0.000657
Inside refresh.cs at SaveViewState 0.001885 0.000344
aspx.page End SaveViewState 0.001929 0.000044
aspx.page Begin Render 0.001956 0.000027
aspx.page End Render 0.111191 0.109235

Just to make sure my code was working correctly, I rewrote the class to
do nothing except what is done normally.

namespace MyFunctions
{
public class Page : System.Web.UI.Page
{
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}

protected override object SaveViewState()
{
Trace.Warn("Inside refresh.cs at SaveViewState");
return base.SaveViewState();
}
}
}



I am still getting the same results.

It calls the SaveViewState twice. This is not what the documentations
say (at least not that I can find).

Am I missing something?

Thanks,

Tom
 
S

Scott M.

I don't know why trace=true causes 2 SVS calls, but I can only assume it is
because the page class calls it the first time and the addition of the trace
info. to the page's render data calls it again.

As for my preference for doing the work in the Page_Load, rather than LVS
and SVS and the use of Sessions...

I used sessions myself back in classic ASP because they were easy and (short
of more permenant data storage), they seemed like the best overall deal in
town. But sessions, as I'm sure you know, are not the most efficient
mechanism for persisting state and also not the most reliable. Now, that
ASP.NET gives us ViewState and the Cache, I like those instead of Sessions.
Also, sessions present additional problems when applications scale to web
farms.

The actual code can be placed in several different events, but it just seems
(to me anyway) that Page_Load is the more logical choice than LVS and SVS,
since to most people it is not obvious which event fires and when (LVS
doesn't fire at all on the first page call).

Anyway, good luck!


tshad said:
Scott M. said:
Your code is using sessions for storage and retrieval of data, but you
are talking about viewstate. Session data and ViewState data are not the
same thing.

Also, you still seem to be saying that SVS is firing twice because of an
assumption, not because of a fact. Take all your code out of SVS and
just place a dummy line of code (create a variable and assign it a
value). Set a breakpoint on this line and execute your code (with
debugging) and step (line by line) through the code. I really think
under this scenario, you will see SVS fires only once per page request.

Lastly, even if you wish to add to ViewState, I still wouldn't do it from
within the SVS or LVS events. Do it from Page_Load and use IsPostBack if
needed.

I got this from:

http://jarednevans.typepad.com/technoblog/2005/01/jareds_techno_b.html

It does seem to work fine for Pages that have already been posted back,
but doesn't work for initial pages that are being refreshed. This is
because the LoadViewState doesn't fire. I was looking at using a session
variable (similar to Dino Espositos solution that is mentioned in the
above article) is some way to handle this.

What is your reason for not doing it this way? Is it that you don't like
the base Page Class setup? I want to set this up so that all my using it
and this seemed like a pretty good place to do this (except for the
LoadViewState problem - which I am looking at).
I belive you are not getting the results you want because of the code you
wrote and not because the SVS event is working incorrectly.

You were right. It wasn't what I wrote but that I had the trace set to
true. This causes the SVS to fire a second time (I assume the event that
fires between the normal page events is from this).

This is why it was confusing. It would work fine then all of a sudden it
wouldn't.

Using the following:
*************************************
using System;
using System.Web;
using System.Web.SessionState;

namespace MyFunctions
{
public class Page : System.Web.UI.Page
{
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}

protected override object SaveViewState()
{
return base.SaveViewState();
}
}
}
**********************************************

Works fine if trace="false", but fires a 2nd time if trace="true".

Do you know why it does that?

Thanks,

Tom
tshad said:
First, I would try setting breakpoints and stepping through your code
line by line to verify your assertion that SVS is firing twice during
one page request, rather than assume this is the case by looking at the
trace. The trace is not necessarially an event by event listing of
what happend during the page request. It's more of a stage by stage
description.


I only did that to check if the code was working correctly.

Second, I wouldn't be adding any code to the LVS or the SVS event
handlers unless that code has to do with the loading or saving of
viewstate. Writing out to a text file doesn't need to be done here.
Use Page_Load instead.

The actual code was loading data into the viewstate.

I was writing into my textfile only to see what was happening.

What I found was that the SaveViewState was being fired twice because on
the first Session(ISREFRESH) was equal to nothing and on the second time
it was fired it would be "false"

At start of SaveViewState - _refreshState = False Session(ISREFRESH)
= isRefresh = False
At End of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False

At start of SaveViewState - _refreshState = False Session(ISREFRESH)
= False isRefresh = False
At End of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False


********************************************************************************************
protected override object SaveViewState()
{
bool _isrefresh = false;
string _tname = "__Ticket";

FileStream fs = new
FileStream("c:\\inetpub\\wwwroot\\staffingworkshop\\uploads\\tfsRefresh.txt",
FileMode.Append, FileAccess.Write);
StreamWriter s = new StreamWriter(fs);
s.BaseStream.Seek(0,SeekOrigin.End);
s.WriteLine(" ");
s.WriteLine("C# Version");
s.WriteLine("At start of SaveViewState - _refreshState = " +
_refreshState + " Session(ISREFRESH) = " + Session["__ISREFRESH"] + "
isRefresh = " + _isRefresh);
Session["__ISREFRESH"] = _refreshState;
object[] allStates = new object[2];
allStates[0] = base.SaveViewState();
allStates[1] = !_refreshState;
s.WriteLine("At End of SaveViewState - _refreshState = " + _refreshState
+ " Session(ISREFRESH) = " + Session["__ISREFRESH"] + " isRefresh = "
+ _isRefresh);
s.Close();
return allStates;
}
}
**********************************************************************************

The thing is this didn't use to be the case. I looked at my old text
file and it was only firing once. Something is causing it to fire twice
now. I started stripping out code to see if something I was doing was
causing the problem, but when I got it down to the bare minimum, it was
still doing it.

This was driving me crazy as there didn't seem to be any rhyme or reason
for this happening. As you can see from below there is nothing there.
So what could be causing it. I tried restarting my machine to see if
there was a problem there, but that didn't do it.

Tom


I thought I understood how the SaveViewState is working and was trying
to use this (as per some code I found) to detect refreshes. It seemed
to be working but I found that the SaveViewState was executing twice on
load of page and can't figure out why.

I was writing out to a text file in the SaveViewState event and it was
writing it twice everytime a page was loaded (whether on an initial
load of the page or Postback).

I took out the writes to the text file and added the "trace.warn" to
see where it was happening.

The thing I noticed is that the first SaveViewState is executing
outside all the Events.

It is executing after the End of the PreRender and before the Start of
the normal SaveViewState.

aspx.page Begin Init
aspx.page End Init 0.000072 0.000072
aspx.page Begin PreRender 0.000111 0.000039
aspx.page End PreRender 0.000160 0.000049
Inside refresh.cs at SaveViewState 0.000884 0.000725
aspx.page Begin SaveViewState 0.001542 0.000657
Inside refresh.cs at SaveViewState 0.001885 0.000344
aspx.page End SaveViewState 0.001929 0.000044
aspx.page Begin Render 0.001956 0.000027
aspx.page End Render 0.111191 0.109235

Just to make sure my code was working correctly, I rewrote the class
to do nothing except what is done normally.

namespace MyFunctions
{
public class Page : System.Web.UI.Page
{
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}

protected override object SaveViewState()
{
Trace.Warn("Inside refresh.cs at SaveViewState");
return base.SaveViewState();
}
}
}



I am still getting the same results.

It calls the SaveViewState twice. This is not what the documentations
say (at least not that I can find).

Am I missing something?

Thanks,

Tom
 
T

tshad

Scott M. said:
I don't know why trace=true causes 2 SVS calls, but I can only assume it is
because the page class calls it the first time and the addition of the
trace info. to the page's render data calls it again.

As for my preference for doing the work in the Page_Load, rather than LVS
and SVS and the use of Sessions...

I used sessions myself back in classic ASP because they were easy and
(short of more permenant data storage), they seemed like the best overall
deal in town. But sessions, as I'm sure you know, are not the most
efficient mechanism for persisting state and also not the most reliable.
Now, that ASP.NET gives us ViewState and the Cache, I like those instead
of Sessions. Also, sessions present additional problems when applications
scale to web farms.

I haven't used the Cache, myself as I started using Sessions a while ago and
most of my application already depends on them. I know that this is going
to be a problem if I move this to a web farm and will need to deal that
problem at that time.

I use viewstate as well as sessions. I was using the LVS and SVS mainly as
a place to setup my session variables and check for refresh using a property
IsRefresh, just like we use IsPostBack and IsValid. This seems pretty
logical to me.

I don't want to use Page_Load if I am going to have to go to each page to
add this code and have to deal with whether we are dealing with an initial
page load or post back. I would prefer to deal with it in one place and
just call IsRefresh as needed. It seemed that LVS and SVS was a logical
place to do this or use an HTTPModule. I found these approaches in a couple
of articles on the web. The problem with the article on the HTTPModule was
that the author (Dino Espisito, I think) was creating a control on each page
that needed to do the check. This seemed like a little overkill - but the
HTTPModule might be a good place to do this, however. The LVS/SVS approach
has the problem we talked about where the LVS is not called if not a
PostBack, but works otherwise (unless Trace is enabled. This could cause a
problem if using Trace to debug).

The problem with the HTTPModule is that I can't seem to get it to run.

Thanks,

Tom
The actual code can be placed in several different events, but it just
seems (to me anyway) that Page_Load is the more logical choice than LVS
and SVS, since to most people it is not obvious which event fires and when
(LVS doesn't fire at all on the first page call).

Anyway, good luck!


tshad said:
Scott M. said:
Your code is using sessions for storage and retrieval of data, but you
are talking about viewstate. Session data and ViewState data are not
the same thing.

Also, you still seem to be saying that SVS is firing twice because of an
assumption, not because of a fact. Take all your code out of SVS and
just place a dummy line of code (create a variable and assign it a
value). Set a breakpoint on this line and execute your code (with
debugging) and step (line by line) through the code. I really think
under this scenario, you will see SVS fires only once per page request.

Lastly, even if you wish to add to ViewState, I still wouldn't do it
from within the SVS or LVS events. Do it from Page_Load and use
IsPostBack if needed.

I got this from:

http://jarednevans.typepad.com/technoblog/2005/01/jareds_techno_b.html

It does seem to work fine for Pages that have already been posted back,
but doesn't work for initial pages that are being refreshed. This is
because the LoadViewState doesn't fire. I was looking at using a session
variable (similar to Dino Espositos solution that is mentioned in the
above article) is some way to handle this.

What is your reason for not doing it this way? Is it that you don't like
the base Page Class setup? I want to set this up so that all my using it
and this seemed like a pretty good place to do this (except for the
LoadViewState problem - which I am looking at).
I belive you are not getting the results you want because of the code
you wrote and not because the SVS event is working incorrectly.

You were right. It wasn't what I wrote but that I had the trace set to
true. This causes the SVS to fire a second time (I assume the event that
fires between the normal page events is from this).

This is why it was confusing. It would work fine then all of a sudden it
wouldn't.

Using the following:
*************************************
using System;
using System.Web;
using System.Web.SessionState;

namespace MyFunctions
{
public class Page : System.Web.UI.Page
{
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}

protected override object SaveViewState()
{
return base.SaveViewState();
}
}
}
**********************************************

Works fine if trace="false", but fires a 2nd time if trace="true".

Do you know why it does that?

Thanks,

Tom
First, I would try setting breakpoints and stepping through your code
line by line to verify your assertion that SVS is firing twice during
one page request, rather than assume this is the case by looking at
the trace. The trace is not necessarially an event by event listing
of what happend during the page request. It's more of a stage by
stage description.


I only did that to check if the code was working correctly.

Second, I wouldn't be adding any code to the LVS or the SVS event
handlers unless that code has to do with the loading or saving of
viewstate. Writing out to a text file doesn't need to be done here.
Use Page_Load instead.

The actual code was loading data into the viewstate.

I was writing into my textfile only to see what was happening.

What I found was that the SaveViewState was being fired twice because
on the first Session(ISREFRESH) was equal to nothing and on the second
time it was fired it would be "false"

At start of SaveViewState - _refreshState = False Session(ISREFRESH)
= isRefresh = False
At End of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False

At start of SaveViewState - _refreshState = False Session(ISREFRESH)
= False isRefresh = False
At End of SaveViewState - _refreshState = False Session(ISREFRESH) =
False isRefresh = False


********************************************************************************************
protected override object SaveViewState()
{
bool _isrefresh = false;
string _tname = "__Ticket";

FileStream fs = new
FileStream("c:\\inetpub\\wwwroot\\staffingworkshop\\uploads\\tfsRefresh.txt",
FileMode.Append, FileAccess.Write);
StreamWriter s = new StreamWriter(fs);
s.BaseStream.Seek(0,SeekOrigin.End);
s.WriteLine(" ");
s.WriteLine("C# Version");
s.WriteLine("At start of SaveViewState - _refreshState = " +
_refreshState + " Session(ISREFRESH) = " + Session["__ISREFRESH"] +
" isRefresh = " + _isRefresh);
Session["__ISREFRESH"] = _refreshState;
object[] allStates = new object[2];
allStates[0] = base.SaveViewState();
allStates[1] = !_refreshState;
s.WriteLine("At End of SaveViewState - _refreshState = " +
_refreshState + " Session(ISREFRESH) = " + Session["__ISREFRESH"] + "
isRefresh = " + _isRefresh);
s.Close();
return allStates;
}
}
**********************************************************************************

The thing is this didn't use to be the case. I looked at my old text
file and it was only firing once. Something is causing it to fire
twice now. I started stripping out code to see if something I was doing
was causing the problem, but when I got it down to the bare minimum, it
was still doing it.

This was driving me crazy as there didn't seem to be any rhyme or
reason for this happening. As you can see from below there is nothing
there. So what could be causing it. I tried restarting my machine to
see if there was a problem there, but that didn't do it.

Tom


I thought I understood how the SaveViewState is working and was trying
to use this (as per some code I found) to detect refreshes. It seemed
to be working but I found that the SaveViewState was executing twice
on load of page and can't figure out why.

I was writing out to a text file in the SaveViewState event and it
was writing it twice everytime a page was loaded (whether on an
initial load of the page or Postback).

I took out the writes to the text file and added the "trace.warn" to
see where it was happening.

The thing I noticed is that the first SaveViewState is executing
outside all the Events.

It is executing after the End of the PreRender and before the Start
of the normal SaveViewState.

aspx.page Begin Init
aspx.page End Init 0.000072 0.000072
aspx.page Begin PreRender 0.000111 0.000039
aspx.page End PreRender 0.000160 0.000049
Inside refresh.cs at SaveViewState 0.000884 0.000725
aspx.page Begin SaveViewState 0.001542 0.000657
Inside refresh.cs at SaveViewState 0.001885 0.000344
aspx.page End SaveViewState 0.001929 0.000044
aspx.page Begin Render 0.001956 0.000027
aspx.page End Render 0.111191 0.109235

Just to make sure my code was working correctly, I rewrote the class
to do nothing except what is done normally.

namespace MyFunctions
{
public class Page : System.Web.UI.Page
{
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}

protected override object SaveViewState()
{
Trace.Warn("Inside refresh.cs at SaveViewState");
return base.SaveViewState();
}
}
}



I am still getting the same results.

It calls the SaveViewState twice. This is not what the documentations
say (at least not that I can find).

Am I missing something?

Thanks,

Tom
 
T

tshad

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 .
***************************************************************************
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;
}
}
}
****************************************************************************

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

tshad said:
Scott M. said:
I don't know why trace=true causes 2 SVS calls, but I can only assume it
is because the page class calls it the first time and the addition of the
trace info. to the page's render data calls it again.

As for my preference for doing the work in the Page_Load, rather than LVS
and SVS and the use of Sessions...

I used sessions myself back in classic ASP because they were easy and
(short of more permenant data storage), they seemed like the best overall
deal in town. But sessions, as I'm sure you know, are not the most
efficient mechanism for persisting state and also not the most reliable.
Now, that ASP.NET gives us ViewState and the Cache, I like those instead
of Sessions. Also, sessions present additional problems when applications
scale to web farms.

I haven't used the Cache, myself as I started using Sessions a while ago
and most of my application already depends on them. I know that this is
going to be a problem if I move this to a web farm and will need to deal
that problem at that time.

I use viewstate as well as sessions. I was using the LVS and SVS mainly
as a place to setup my session variables and check for refresh using a
property IsRefresh, just like we use IsPostBack and IsValid. This seems
pretty logical to me.

I don't want to use Page_Load if I am going to have to go to each page to
add this code and have to deal with whether we are dealing with an initial
page load or post back. I would prefer to deal with it in one place and
just call IsRefresh as needed. It seemed that LVS and SVS was a logical
place to do this or use an HTTPModule. I found these approaches in a
couple of articles on the web. The problem with the article on the
HTTPModule was that the author (Dino Espisito, I think) was creating a
control on each page that needed to do the check. This seemed like a
little overkill - but the HTTPModule might be a good place to do this,
however. The LVS/SVS approach has the problem we talked about where the
LVS is not called if not a PostBack, but works otherwise (unless Trace is
enabled. This could cause a problem if using Trace to debug).

The problem with the HTTPModule is that I can't seem to get it to run.

Thanks,

Tom
The actual code can be placed in several different events, but it just
seems (to me anyway) that Page_Load is the more logical choice than LVS
and SVS, since to most people it is not obvious which event fires and
when (LVS doesn't fire at all on the first page call).

Anyway, good luck!


tshad said:
Your code is using sessions for storage and retrieval of data, but you
are talking about viewstate. Session data and ViewState data are not
the same thing.

Also, you still seem to be saying that SVS is firing twice because of
an assumption, not because of a fact. Take all your code out of SVS
and just place a dummy line of code (create a variable and assign it a
value). Set a breakpoint on this line and execute your code (with
debugging) and step (line by line) through the code. I really think
under this scenario, you will see SVS fires only once per page request.

Lastly, even if you wish to add to ViewState, I still wouldn't do it
from within the SVS or LVS events. Do it from Page_Load and use
IsPostBack if needed.

I got this from:

http://jarednevans.typepad.com/technoblog/2005/01/jareds_techno_b.html

It does seem to work fine for Pages that have already been posted back,
but doesn't work for initial pages that are being refreshed. This is
because the LoadViewState doesn't fire. I was looking at using a
session variable (similar to Dino Espositos solution that is mentioned
in the above article) is some way to handle this.

What is your reason for not doing it this way? Is it that you don't
like the base Page Class setup? I want to set this up so that all my
using it and this seemed like a pretty good place to do this (except for
the LoadViewState problem - which I am looking at).


I belive you are not getting the results you want because of the code
you wrote and not because the SVS event is working incorrectly.

You were right. It wasn't what I wrote but that I had the trace set to
true. This causes the SVS to fire a second time (I assume the event that
fires between the normal page events is from this).

This is why it was confusing. It would work fine then all of a sudden
it wouldn't.

Using the following:
*************************************
using System;
using System.Web;
using System.Web.SessionState;

namespace MyFunctions
{
public class Page : System.Web.UI.Page
{
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}

protected override object SaveViewState()
{
return base.SaveViewState();
}
}
}
**********************************************

Works fine if trace="false", but fires a 2nd time if trace="true".

Do you know why it does that?

Thanks,

Tom




First, I would try setting breakpoints and stepping through your code
line by line to verify your assertion that SVS is firing twice during
one page request, rather than assume this is the case by looking at
the trace. The trace is not necessarially an event by event listing
of what happend during the page request. It's more of a stage by
stage description.


I only did that to check if the code was working correctly.

Second, I wouldn't be adding any code to the LVS or the SVS event
handlers unless that code has to do with the loading or saving of
viewstate. Writing out to a text file doesn't need to be done here.
Use Page_Load instead.

The actual code was loading data into the viewstate.

I was writing into my textfile only to see what was happening.

What I found was that the SaveViewState was being fired twice because
on the first Session(ISREFRESH) was equal to nothing and on the second
time it was fired it would be "false"

At start of SaveViewState - _refreshState = False
Session(ISREFRESH) = isRefresh = False
At End of SaveViewState - _refreshState = False Session(ISREFRESH)
= False isRefresh = False

At start of SaveViewState - _refreshState = False
Session(ISREFRESH) = False isRefresh = False
At End of SaveViewState - _refreshState = False Session(ISREFRESH)
= False isRefresh = False


********************************************************************************************
protected override object SaveViewState()
{
bool _isrefresh = false;
string _tname = "__Ticket";

FileStream fs = new
FileStream("c:\\inetpub\\wwwroot\\staffingworkshop\\uploads\\tfsRefresh.txt",
FileMode.Append, FileAccess.Write);
StreamWriter s = new StreamWriter(fs);
s.BaseStream.Seek(0,SeekOrigin.End);
s.WriteLine(" ");
s.WriteLine("C# Version");
s.WriteLine("At start of SaveViewState - _refreshState = " +
_refreshState + " Session(ISREFRESH) = " + Session["__ISREFRESH"] +
" isRefresh = " + _isRefresh);
Session["__ISREFRESH"] = _refreshState;
object[] allStates = new object[2];
allStates[0] = base.SaveViewState();
allStates[1] = !_refreshState;
s.WriteLine("At End of SaveViewState - _refreshState = " +
_refreshState + " Session(ISREFRESH) = " + Session["__ISREFRESH"] + "
isRefresh = " + _isRefresh);
s.Close();
return allStates;
}
}
**********************************************************************************

The thing is this didn't use to be the case. I looked at my old text
file and it was only firing once. Something is causing it to fire
twice now. I started stripping out code to see if something I was
doing was causing the problem, but when I got it down to the bare
minimum, it was still doing it.

This was driving me crazy as there didn't seem to be any rhyme or
reason for this happening. As you can see from below there is nothing
there. So what could be causing it. I tried restarting my machine to
see if there was a problem there, but that didn't do it.

Tom


I thought I understood how the SaveViewState is working and was
trying to use this (as per some code I found) to detect refreshes.
It seemed to be working but I found that the SaveViewState was
executing twice on load of page and can't figure out why.

I was writing out to a text file in the SaveViewState event and it
was writing it twice everytime a page was loaded (whether on an
initial load of the page or Postback).

I took out the writes to the text file and added the "trace.warn" to
see where it was happening.

The thing I noticed is that the first SaveViewState is executing
outside all the Events.

It is executing after the End of the PreRender and before the Start
of the normal SaveViewState.

aspx.page Begin Init
aspx.page End Init 0.000072 0.000072
aspx.page Begin PreRender 0.000111 0.000039
aspx.page End PreRender 0.000160 0.000049
Inside refresh.cs at SaveViewState 0.000884 0.000725
aspx.page Begin SaveViewState 0.001542 0.000657
Inside refresh.cs at SaveViewState 0.001885 0.000344
aspx.page End SaveViewState 0.001929 0.000044
aspx.page Begin Render 0.001956 0.000027
aspx.page End Render 0.111191 0.109235

Just to make sure my code was working correctly, I rewrote the class
to do nothing except what is done normally.

namespace MyFunctions
{
public class Page : System.Web.UI.Page
{
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}

protected override object SaveViewState()
{
Trace.Warn("Inside refresh.cs at SaveViewState");
return base.SaveViewState();
}
}
}



I am still getting the same results.

It calls the SaveViewState twice. This is not what the
documentations say (at least not that I can find).

Am I missing something?

Thanks,

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top