Viewstate

F

Frank

I have a question concerning Viewstate and how it relates
to a Control's event handler (if at all). I did not think
there was any association between a Control's viewstate
and an event handler until I attempted to clear Viewstate
from the Page.

Here is the problem I am facing: in our system, we do not
want to use Viewstate at all. We have a framework in which
all controls are dynamically created for a page (for
better or for worse).

However, when we set EnableViewState to false (at any
level), there remains some Viewstate generated for the
page. Things get worse when we dynamically generate
CheckBox controls and add them as child controls to a
DataGrid-the Viewstate size becomes very large.

I implemented overrides for
LoadPageStateFromPersistenceMedium and
SavePageStateToPersistenceMedium methods for our base Page
class. Essentially, for Load... I return null and for
Save... I do nothing. This works great since Viewstate on
the client now contains 0 bytes in all cases. There is
only one problem-the event handlers for the click events
on all of our ImageButtons do not work now. How could this
be? Is there some association between a server control's
event handler and it's Viewstate? or is this a bug? If so,
what could be a workaround?
 
L

Lostinet.Web Support

if you don't use ViewState , don't use <Form runat=server> too.
if you want postback,ViewState is very important.
some controls (i.e. DataGrid) use ViewState to store items count,
if ViewState disabled , DataGrid will display nothing when postback.

maybe these code can help you:

namespace Web
{
using System;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;

using System.Threading;
using System.Diagnostics;

public class LightStatePage : System.Web.UI.Page
{

#region HashCodeLock
private class HashCodeLockTimeoutException:Exception
{
public HashCodeLockTimeoutException(string msg):base(msg){}
}

/// <remarks>
/// <code>
/// using(new LostinetSample.HashCodeLock(111))
/// {
/// //now this thread is synchronized for int 111
/// }
/// </code>
/// </remarks>
private sealed class HashCodeLock:IDisposable
{
class Allocator
{
class Node
{
int typecode;
int hashcode;
public Node(object obj)
{
typecode=obj.GetType().GetHashCode();
hashcode=obj.GetHashCode();
}
override public bool Equals(object obj)
{
if(obj == null)
return false;
if(obj is Node)
{
Node n=(Node)obj;
return n.typecode==typecode&&n.hashcode==hashcode;
}
return false;
}
override public int GetHashCode()
{
return typecode+hashcode;
}
}

static ArrayList al=new ArrayList();
static public object Alloc(object obj)
{
object n=new Node(obj);
lock(al.SyncRoot)
{
int index=al.IndexOf(n);
if(index!=-1)
{
n=al[index];
}
al.Add(n);
return n;
}
}
static public object Release(object obj)
{
object n=new Node(obj);
lock(al.SyncRoot)
{
int index=al.IndexOf(n);
if(index==-1)
throw(new Exception("cant release obj:node not found"));
n=al[index];
al.RemoveAt(index);
return n;
}
}
}


public HashCodeLock(object obj):this(obj,Timeout.Infinite)
{
}
public HashCodeLock(object obj,TimeSpan
tsTimeout):this(obj,(int)tsTimeout.TotalMilliseconds)
{
}
public HashCodeLock(object obj,int msTimeout)
{
if(obj==null)throw(new ArgumentNullException("obj"));

SetM();

if(!Monitor.TryEnter(Allocator.Alloc(obj),msTimeout))
{
Allocator.Release(obj);
throw(new HashCodeLockTimeoutException("lock timeout"));
}
o=obj;
released=false;
}

[Conditional("DEBUG")]
void SetM()
{
StackTrace st=new StackTrace();
for(int i=0;i<st.FrameCount;i++)
{
MethodBase mb=st.GetFrame(i).GetMethod();
if(mb.ReflectedType!=typeof(HashCodeLock))
{
m=mb.ReflectedType.FullName+":"+mb.ToString();
break;
}
}
}

bool released=true;
object o;
string m=" unknown method (not query in release) ";

void IDisposable.Dispose()
{
if(released)
throw(new Exception("lock at "+m+" already released!"));
released=true;
Monitor.Exit(Allocator.Release(o));
}
~HashCodeLock()
{
if(!released)
throw(new Exception("lock at "+m+" have not released!"));
}
}
#endregion

protected LightStatePage()
{
}

protected virtual bool EnableDiskViewState
{
get
{
return true;
}
}

protected override object LoadPageStateFromPersistenceMedium()
{
if(EnableDiskViewState)
{
DateTime time=new
DateTime(long.Parse((string)base.LoadPageStateFromPersistenceMedium()));;

LosFormatter lf=new LosFormatter();
using(new HashCodeLock(time))
{
using(Stream s=LoadPagePersistenceStream(time))
{
return lf.Deserialize(s);
}
}
}
else
{
return base.LoadPageStateFromPersistenceMedium();
}
}
protected override void SavePageStateToPersistenceMedium(object
viewLightPageState)
{
if(EnableDiskViewState)
{
LosFormatter lf=new LosFormatter();
using(new HashCodeLock(_time))
{
using(Stream s=SavePagePersistanceStream(_time))
{
lf.Serialize(s,viewLightPageState);
}
}

base.SavePageStateToPersistenceMedium(_time.Ticks.ToString());
}
else
{
base.SavePageStateToPersistenceMedium(viewLightPageState);
}
}

static string GetSiteName(HttpContext context)
{
string applmdpath;

try
{
applmdpath=context.Request.ServerVariables["APPL_MD_PATH"];
}
catch
{
HttpWorkerRequest wr=(HttpWorkerRequest)
typeof(HttpContext).InvokeMember("get_WorkerRequest"

,BindingFlags.InvokeMethod|BindingFlags.Instance|BindingFlags.Public|Binding
Flags.NonPublic
,null,context,new object[]{}
);
applmdpath=wr.GetServerVariable("APPL_MD_PATH");
}
applmdpath=applmdpath.Replace("/","_");
return applmdpath;
}

#region ?????
override protected void OnInit(EventArgs e)
{
//??Request.ServerVariables?????
GetSiteName(Context);

if(new Random(Guid.NewGuid().GetHashCode()).Next(1000)==1)
{
ClearCacheHandler handler=new ClearCacheHandler(ClearCacheAsync);
handler.BeginInvoke(Context,null,null);
}

base.OnInit(e);
}

delegate void ClearCacheHandler(HttpContext context);
static void ClearCacheAsync(HttpContext context)
{
string sitename=GetSiteName(context);
string rootdir=Path.GetTempPath()+"LightStatePageTemp\\"+sitename+"\\";
if(!Directory.Exists(rootdir))
return;
using(new HashCodeLock("ClearCacheHandler:"+sitename))
{
string str1=rootdir+DateTime.Now.ToString("yyyy-MM-dd HH");
string str2=rootdir+DateTime.Now.AddHours(-1).ToString("yyyy-MM-dd HH");

foreach(string dir in Directory.GetDirectories(rootdir))
{
if(dir==str1||dir==str2)
continue;
try
{
DeleteDirectory(dir);
}
catch(Exception x)
{
try
{
using(FileStream fs=new
FileStream(Path.Combine(context.Request.PhysicalApplicationPath,"LightStateP
age_ErrorLog.txt"),FileMode.Append))
{
using(StreamWriter sw=new StreamWriter(fs))
{
sw.Write(sitename+"???,????"+dir+"??????"+x.ToString());
sw.Write("\r\n\r\n\r\n");
}
}
}
catch
{
}
}
}
}
}
static void DeleteDirectory(string dir)
{
foreach(string subdir in Directory.GetDirectories(dir))
{
DeleteDirectory(subdir);
}
foreach(string file in Directory.GetFiles(dir))
{
File.Delete(file);
}
Directory.Delete(dir);
}
#endregion

private DateTime _time=DateTime.Now;

protected virtual string GetPegePersistenceFileName(DateTime time)
{
return Path.GetTempPath()
+"LightStatePageTemp\\"
+GetSiteName(Context)+"\\"
+time.ToString("yyyy-MM-dd HH")+"\\"
+Session.SessionID+"\\"
+Request.FilePath+"\\"
+time.Ticks.ToString()
+".txt";
}

protected virtual Stream LoadPagePersistenceStream(DateTime time)
{
string filePath=GetPegePersistenceFileName(time);
return new FileStream(filePath,FileMode.Open,FileAccess.Read);
}
protected virtual Stream SavePagePersistanceStream(DateTime time)
{
string filePath=GetPegePersistenceFileName(time);
try
{
return new FileStream(filePath,FileMode.Create);
}
catch
{
string
str=filePath.Substring(0,Math.Max(filePath.LastIndexOf("\\"),filePath.LastIn
dexOf("/")));
CreateDirecotry(str);
return new FileStream(filePath,FileMode.Create);
}
}
protected void CreateDirecotry(string dir)
{
if(dir==null)
throw(new ArgumentNullException("null"));
if(dir.Length==0)
throw(new Exception("???dir"));
try
{
Directory.CreateDirectory(dir);
}
catch
{
string
str=dir.Substring(0,Math.Max(dir.LastIndexOf("\\"),dir.LastIndexOf("/")));
if(str==dir)
throw(new Exception("????DIR:"+dir));
CreateDirecotry(str);
}
}
}
}
 
G

Guest

So if I don't use Viewstate, I cannot use server-side
event processing either, correct?

-----Original Message-----
if you don't use ViewState , don't use <Form runat=server> too.
if you want postback,ViewState is very important.
some controls (i.e. DataGrid) use ViewState to store items count,
if ViewState disabled , DataGrid will display nothing when postback.

maybe these code can help you:

namespace Web
{
using System;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;

using System.Threading;
using System.Diagnostics;

public class LightStatePage : System.Web.UI.Page
{

#region HashCodeLock
private class HashCodeLockTimeoutException:Exception
{
public HashCodeLockTimeoutException(string msg):base (msg){}
}

/// <remarks>
/// <code>
/// using(new LostinetSample.HashCodeLock(111))
/// {
/// //now this thread is synchronized for int 111
/// }
/// </code>
/// </remarks>
private sealed class HashCodeLock:IDisposable
{
class Allocator
{
class Node
{
int typecode;
int hashcode;
public Node(object obj)
{
typecode=obj.GetType().GetHashCode();
hashcode=obj.GetHashCode();
}
override public bool Equals(object obj)
{
if(obj == null)
return false;
if(obj is Node)
{
Node n=(Node)obj;
return n.typecode==typecode&&n.hashcode==hashcode;
}
return false;
}
override public int GetHashCode()
{
return typecode+hashcode;
}
}

static ArrayList al=new ArrayList();
static public object Alloc(object obj)
{
object n=new Node(obj);
lock(al.SyncRoot)
{
int index=al.IndexOf(n);
if(index!=-1)
{
n=al[index];
}
al.Add(n);
return n;
}
}
static public object Release(object obj)
{
object n=new Node(obj);
lock(al.SyncRoot)
{
int index=al.IndexOf(n);
if(index==-1)
throw(new Exception("cant release obj:node not found"));
n=al[index];
al.RemoveAt(index);
return n;
}
}
}


public HashCodeLock(object obj):this (obj,Timeout.Infinite)
{
}
public HashCodeLock(object obj,TimeSpan
tsTimeout):this(obj,(int)tsTimeout.TotalMilliseconds)
{
}
public HashCodeLock(object obj,int msTimeout)
{
if(obj==null)throw(new ArgumentNullException("obj"));

SetM();

if(!Monitor.TryEnter(Allocator.Alloc(obj),msTimeout))
{
Allocator.Release(obj);
throw(new HashCodeLockTimeoutException("lock timeout"));
}
o=obj;
released=false;
}

[Conditional("DEBUG")]
void SetM()
{
StackTrace st=new StackTrace();
for(int i=0;i<st.FrameCount;i++)
{
MethodBase mb=st.GetFrame(i).GetMethod();
if(mb.ReflectedType!=typeof(HashCodeLock))
{
m=mb.ReflectedType.FullName+":"+mb.ToString();
break;
}
}
}

bool released=true;
object o;
string m=" unknown method (not query in release) ";

void IDisposable.Dispose()
{
if(released)
throw(new Exception("lock at "+m+" already released!"));
released=true;
Monitor.Exit(Allocator.Release(o));
}
~HashCodeLock()
{
if(!released)
throw(new Exception("lock at "+m+" have not released!"));
}
}
#endregion

protected LightStatePage()
{
}

protected virtual bool EnableDiskViewState
{
get
{
return true;
}
}

protected override object LoadPageStateFromPersistenceMedium()
{
if(EnableDiskViewState)
{
DateTime time=new
DateTime(long.Parse((string) base.LoadPageStateFromPersistenceMedium()));;

LosFormatter lf=new LosFormatter();
using(new HashCodeLock(time))
{
using(Stream s=LoadPagePersistenceStream(time))
{
return lf.Deserialize(s);
}
}
}
else
{
return base.LoadPageStateFromPersistenceMedium();
}
}
protected override void SavePageStateToPersistenceMedium (object
viewLightPageState)
{
if(EnableDiskViewState)
{
LosFormatter lf=new LosFormatter();
using(new HashCodeLock(_time))
{
using(Stream s=SavePagePersistanceStream(_time))
{
lf.Serialize(s,viewLightPageState);
}
}

base.SavePageStateToPersistenceMedium (_time.Ticks.ToString());
}
else
{
base.SavePageStateToPersistenceMedium
(viewLightPageState);
}
}

static string GetSiteName(HttpContext context)
{
string applmdpath;

try
{
applmdpath=context.Request.ServerVariables ["APPL_MD_PATH"];
}
catch
{
HttpWorkerRequest wr=(HttpWorkerRequest)
typeof(HttpContext).InvokeMember("get_WorkerRequest"

,BindingFlags.InvokeMethod|BindingFlags.Instance|BindingFl ags.Public|Binding
Flags.NonPublic
,null,context,new object[]{}
);
applmdpath=wr.GetServerVariable("APPL_MD_PATH");
}
applmdpath=applmdpath.Replace("/","_");
return applmdpath;
}

#region ?????
override protected void OnInit(EventArgs e)
{
//??Request.ServerVariables?????
GetSiteName(Context);

if(new Random(Guid.NewGuid().GetHashCode()).Next(1000) ==1)
{
ClearCacheHandler handler=new ClearCacheHandler (ClearCacheAsync);
handler.BeginInvoke(Context,null,null);
}

base.OnInit(e);
}

delegate void ClearCacheHandler(HttpContext context);
static void ClearCacheAsync(HttpContext context)
{
string sitename=GetSiteName(context);
string rootdir=Path.GetTempPath() +"LightStatePageTemp\\"+sitename+"\\";
if(!Directory.Exists(rootdir))
return;
using(new HashCodeLock("ClearCacheHandler:"+sitename))
{
string str1=rootdir+DateTime.Now.ToString("yyyy-MM-dd HH");
string str2=rootdir+DateTime.Now.AddHours(-1).ToString ("yyyy-MM-dd HH");

foreach(string dir in Directory.GetDirectories (rootdir))
{
if(dir==str1||dir==str2)
continue;
try
{
DeleteDirectory(dir);
}
catch(Exception x)
{
try
{
using(FileStream fs=new
FileStream(Path.Combine (context.Request.PhysicalApplicationPath,"LightStateP
age_ErrorLog.txt"),FileMode.Append))
{
using(StreamWriter sw=new StreamWriter(fs))
{
sw.Write (sitename+"???,????"+dir+"??????"+x.ToString());
sw.Write("\r\n\r\n\r\n");
}
}
}
catch
{
}
}
}
}
}
static void DeleteDirectory(string dir)
{
foreach(string subdir in Directory.GetDirectories(dir))
{
DeleteDirectory(subdir);
}
foreach(string file in Directory.GetFiles(dir))
{
File.Delete(file);
}
Directory.Delete(dir);
}
#endregion

private DateTime _time=DateTime.Now;

protected virtual string GetPegePersistenceFileName (DateTime time)
{
return Path.GetTempPath()
+"LightStatePageTemp\\"
+GetSiteName(Context)+"\\"
+time.ToString("yyyy-MM-dd HH")+"\\"
+Session.SessionID+"\\"
+Request.FilePath+"\\"
+time.Ticks.ToString()
+".txt";
}

protected virtual Stream LoadPagePersistenceStream (DateTime time)
{
string filePath=GetPegePersistenceFileName(time);
return new FileStream (filePath,FileMode.Open,FileAccess.Read);
}
protected virtual Stream SavePagePersistanceStream (DateTime time)
{
string filePath=GetPegePersistenceFileName(time);
try
{
return new FileStream(filePath,FileMode.Create);
}
catch
{
string
str=filePath.Substring(0,Math.Max(filePath.LastIndexOf ("\\"),filePath.LastIn
dexOf("/")));
CreateDirecotry(str);
return new FileStream(filePath,FileMode.Create);
}
}
protected void CreateDirecotry(string dir)
{
if(dir==null)
throw(new ArgumentNullException("null"));
if(dir.Length==0)
throw(new Exception("???dir"));
try
{
Directory.CreateDirectory(dir);
}
catch
{
string
str=dir.Substring(0,Math.Max(dir.LastIndexOf ("\\"),dir.LastIndexOf("/")));
if(str==dir)
throw(new Exception("????DIR:"+dir));
CreateDirecotry(str);
}
}
}
}

Frank said:
I have a question concerning Viewstate and how it relates
to a Control's event handler (if at all). I did not think
there was any association between a Control's viewstate
and an event handler until I attempted to clear Viewstate
from the Page.

Here is the problem I am facing: in our system, we do not
want to use Viewstate at all. We have a framework in which
all controls are dynamically created for a page (for
better or for worse).

However, when we set EnableViewState to false (at any
level), there remains some Viewstate generated for the
page. Things get worse when we dynamically generate
CheckBox controls and add them as child controls to a
DataGrid-the Viewstate size becomes very large.

I implemented overrides for
LoadPageStateFromPersistenceMedium and
SavePageStateToPersistenceMedium methods for our base Page
class. Essentially, for Load... I return null and for
Save... I do nothing. This works great since Viewstate on
the client now contains 0 bytes in all cases. There is
only one problem-the event handlers for the click events
on all of our ImageButtons do not work now. How could this
be? Is there some association between a server control's
event handler and it's Viewstate? or is this a bug? If so,
what could be a workaround?


.
 

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

No members online now.

Forum statistics

Threads
473,779
Messages
2,569,606
Members
45,239
Latest member
Alex Young

Latest Threads

Top