View state problem

L

Lloyd Dupont

The code snippets are below.

I write in (C#) a Page object in a control library.
I'm using this page as an HtppHandler in a website (which referes the DLL).
This page contains 2 panels (one is visible when the other is not).
When I postback to the page (httphandler) the viewstate is apparently incorrectly restored, that is my 2 panels get visible=false (that is only 1 should be invisible) for no reason I could understand.

Any idea of why is that?

PS: I checked the page, there is a viewstate field with some value... which changes between queries...


===== code in the consumer web site =======

=== IGallery.ashx ==
<%@ WebHandler Language="C#" Class="IGallery" %>

using System;
using System.Web;

using WebUtils;

public class IGallery : FTBImageGallery
{
}

===== code of the WebUtils control library ==========

=== FTBImageGallery.cs ===


namespace WebUtils
{
public class FTBImageGallery : CodePage
{
public override void ProcessRequest(HttpContext context)
{
string imageId = context.Request["getimage"];
if (string.IsNullOrEmpty(imageId))
{
base.ProcessRequest(context);
return;
}
WriteImage(context, imageId);
}

Panel pUpload, pSelect;
protected override void CreateChildControls()
{
base.CreateChildControls();
MainForm.Controls.Add(pUpload = CreateUploadPanel());
MainForm.Controls.Add(pSelect = CreateSelectPanel());
pUpload.Visible = false;
}
Panel CreateSelectPanel()
{
Panel p = new Panel();
p.ID = "select";
// ......
return p;
}
Panel CreateUploadPanel()
{
Panel p = new Panel();
p.ID = "upload";
// ......
return p;
}
}
}

=== CodePage.cs ===
namespace WebUtils
{
public class CodePage : Page
{
public bool ValidateRequest = false;

protected override void FrameworkInitialize()
{
base.FrameworkInitialize();
InitializeCulture();
BuildPage();
Title = Title;
if(ValidateRequest)
Request.ValidateInput();
}

public readonly HtmlForm MainForm = new HtmlForm();
public readonly HtmlHead Head = new HtmlHead();
HtmlTitle pageTitle = new HtmlTitle();
public readonly HtmlGenericControl Body = new HtmlGenericControl("body");

public new string Title
{
get { return base.Title; }
set
{
pageTitle.Text = value;
base.Title = value;
}
}

protected virtual void BuildPage()
{
Head.Controls.Add(pageTitle);
Body.Controls.Add(MainForm);
MainForm.Controls.Add(new LiteralControl("\r\n"));

Controls.Add(new LiteralControl("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\" >\r\n"));
Controls.Add(Head);
Controls.Add(new LiteralControl("\r\n"));
Controls.Add(Body);
Controls.Add(new LiteralControl("\r\n</html>\r\n"));
}
}
}

=================================
 
L

Lloyd Dupont

The problem seems to be triggered by a LinkButton I have on the page in fact.
it has the following reasonable looking code:

LinkButton linkSelectUpload;
protected override void CreateChildControls()
{
base.CreateChildControls();

linkSelectUpload = new LinkButton();
linkSelectUpload.Text = "Upload Images";
linkSelectUpload.Click += HSwitchSelectUpload;
MainForm.Controls.Add(linkSelectUpload);

MainForm.Controls.Add(pUpload = CreateUploadPanel());
MainForm.Controls.Add(pSelect = CreateSelectPanel());
pUpload.Visible = false;
}
void HSwitchSelectUpload(object sender, EventArgs e)
{
pUpload.Visible = !pUpload.Visible;
pSelect.Visible = !pSelect.Visible;
linkSelectUpload.Text = pUpload.Visible ? "Select Image" : "Upload Images";
}
The code snippets are below.

I write in (C#) a Page object in a control library.
I'm using this page as an HtppHandler in a website (which referes the DLL).
This page contains 2 panels (one is visible when the other is not).
When I postback to the page (httphandler) the viewstate is apparently incorrectly restored, that is my 2 panels get visible=false (that is only 1 should be invisible) for no reason I could understand.

Any idea of why is that?

PS: I checked the page, there is a viewstate field with some value... which changes between queries...


===== code in the consumer web site =======

=== IGallery.ashx ==
<%@ WebHandler Language="C#" Class="IGallery" %>

using System;
using System.Web;

using WebUtils;

public class IGallery : FTBImageGallery
{
}

===== code of the WebUtils control library ==========

=== FTBImageGallery.cs ===


namespace WebUtils
{
public class FTBImageGallery : CodePage
{
public override void ProcessRequest(HttpContext context)
{
string imageId = context.Request["getimage"];
if (string.IsNullOrEmpty(imageId))
{
base.ProcessRequest(context);
return;
}
WriteImage(context, imageId);
}

Panel pUpload, pSelect;
protected override void CreateChildControls()
{
base.CreateChildControls();
MainForm.Controls.Add(pUpload = CreateUploadPanel());
MainForm.Controls.Add(pSelect = CreateSelectPanel());
pUpload.Visible = false;
}
Panel CreateSelectPanel()
{
Panel p = new Panel();
p.ID = "select";
// ......
return p;
}
Panel CreateUploadPanel()
{
Panel p = new Panel();
p.ID = "upload";
// ......
return p;
}
}
}

=== CodePage.cs ===
namespace WebUtils
{
public class CodePage : Page
{
public bool ValidateRequest = false;

protected override void FrameworkInitialize()
{
base.FrameworkInitialize();
InitializeCulture();
BuildPage();
Title = Title;
if(ValidateRequest)
Request.ValidateInput();
}

public readonly HtmlForm MainForm = new HtmlForm();
public readonly HtmlHead Head = new HtmlHead();
HtmlTitle pageTitle = new HtmlTitle();
public readonly HtmlGenericControl Body = new HtmlGenericControl("body");

public new string Title
{
get { return base.Title; }
set
{
pageTitle.Text = value;
base.Title = value;
}
}

protected virtual void BuildPage()
{
Head.Controls.Add(pageTitle);
Body.Controls.Add(MainForm);
MainForm.Controls.Add(new LiteralControl("\r\n"));

Controls.Add(new LiteralControl("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\" >\r\n"));
Controls.Add(Head);
Controls.Add(new LiteralControl("\r\n"));
Controls.Add(Body);
Controls.Add(new LiteralControl("\r\n</html>\r\n"));
}
}
}

=================================
 
L

Lloyd Dupont

Haha..
There are some HtmlInputFile which seems to be the cause of the disappearance of the ViewState...
Any idea why?
The code snippets are below.

I write in (C#) a Page object in a control library.
I'm using this page as an HtppHandler in a website (which referes the DLL).
This page contains 2 panels (one is visible when the other is not).
When I postback to the page (httphandler) the viewstate is apparently incorrectly restored, that is my 2 panels get visible=false (that is only 1 should be invisible) for no reason I could understand.

Any idea of why is that?

PS: I checked the page, there is a viewstate field with some value... which changes between queries...


===== code in the consumer web site =======

=== IGallery.ashx ==
<%@ WebHandler Language="C#" Class="IGallery" %>

using System;
using System.Web;

using WebUtils;

public class IGallery : FTBImageGallery
{
}

===== code of the WebUtils control library ==========

=== FTBImageGallery.cs ===


namespace WebUtils
{
public class FTBImageGallery : CodePage
{
public override void ProcessRequest(HttpContext context)
{
string imageId = context.Request["getimage"];
if (string.IsNullOrEmpty(imageId))
{
base.ProcessRequest(context);
return;
}
WriteImage(context, imageId);
}

Panel pUpload, pSelect;
protected override void CreateChildControls()
{
base.CreateChildControls();
MainForm.Controls.Add(pUpload = CreateUploadPanel());
MainForm.Controls.Add(pSelect = CreateSelectPanel());
pUpload.Visible = false;
}
Panel CreateSelectPanel()
{
Panel p = new Panel();
p.ID = "select";
// ......
return p;
}
Panel CreateUploadPanel()
{
Panel p = new Panel();
p.ID = "upload";
// ......
return p;
}
}
}

=== CodePage.cs ===
namespace WebUtils
{
public class CodePage : Page
{
public bool ValidateRequest = false;

protected override void FrameworkInitialize()
{
base.FrameworkInitialize();
InitializeCulture();
BuildPage();
Title = Title;
if(ValidateRequest)
Request.ValidateInput();
}

public readonly HtmlForm MainForm = new HtmlForm();
public readonly HtmlHead Head = new HtmlHead();
HtmlTitle pageTitle = new HtmlTitle();
public readonly HtmlGenericControl Body = new HtmlGenericControl("body");

public new string Title
{
get { return base.Title; }
set
{
pageTitle.Text = value;
base.Title = value;
}
}

protected virtual void BuildPage()
{
Head.Controls.Add(pageTitle);
Body.Controls.Add(MainForm);
MainForm.Controls.Add(new LiteralControl("\r\n"));

Controls.Add(new LiteralControl("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\" >\r\n"));
Controls.Add(Head);
Controls.Add(new LiteralControl("\r\n"));
Controls.Add(Body);
Controls.Add(new LiteralControl("\r\n</html>\r\n"));
}
}
}

=================================
 
L

Lloyd Dupont

Solved!!!

It probably has to do as to when the view state is applied.
If I set panel.Visible = false before adding it to the page, it works!
The code snippets are below.

I write in (C#) a Page object in a control library.
I'm using this page as an HtppHandler in a website (which referes the DLL).
This page contains 2 panels (one is visible when the other is not).
When I postback to the page (httphandler) the viewstate is apparently incorrectly restored, that is my 2 panels get visible=false (that is only 1 should be invisible) for no reason I could understand.

Any idea of why is that?

PS: I checked the page, there is a viewstate field with some value... which changes between queries...


===== code in the consumer web site =======

=== IGallery.ashx ==
<%@ WebHandler Language="C#" Class="IGallery" %>

using System;
using System.Web;

using WebUtils;

public class IGallery : FTBImageGallery
{
}

===== code of the WebUtils control library ==========

=== FTBImageGallery.cs ===


namespace WebUtils
{
public class FTBImageGallery : CodePage
{
public override void ProcessRequest(HttpContext context)
{
string imageId = context.Request["getimage"];
if (string.IsNullOrEmpty(imageId))
{
base.ProcessRequest(context);
return;
}
WriteImage(context, imageId);
}

Panel pUpload, pSelect;
protected override void CreateChildControls()
{
base.CreateChildControls();
MainForm.Controls.Add(pUpload = CreateUploadPanel());
MainForm.Controls.Add(pSelect = CreateSelectPanel());
pUpload.Visible = false;
}
Panel CreateSelectPanel()
{
Panel p = new Panel();
p.ID = "select";
// ......
return p;
}
Panel CreateUploadPanel()
{
Panel p = new Panel();
p.ID = "upload";
// ......
return p;
}
}
}

=== CodePage.cs ===
namespace WebUtils
{
public class CodePage : Page
{
public bool ValidateRequest = false;

protected override void FrameworkInitialize()
{
base.FrameworkInitialize();
InitializeCulture();
BuildPage();
Title = Title;
if(ValidateRequest)
Request.ValidateInput();
}

public readonly HtmlForm MainForm = new HtmlForm();
public readonly HtmlHead Head = new HtmlHead();
HtmlTitle pageTitle = new HtmlTitle();
public readonly HtmlGenericControl Body = new HtmlGenericControl("body");

public new string Title
{
get { return base.Title; }
set
{
pageTitle.Text = value;
base.Title = value;
}
}

protected virtual void BuildPage()
{
Head.Controls.Add(pageTitle);
Body.Controls.Add(MainForm);
MainForm.Controls.Add(new LiteralControl("\r\n"));

Controls.Add(new LiteralControl("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\" >\r\n"));
Controls.Add(Head);
Controls.Add(new LiteralControl("\r\n"));
Controls.Add(Body);
Controls.Add(new LiteralControl("\r\n</html>\r\n"));
}
}
}

=================================
 
S

sam

Yeah, I know why this is.

You have to know about the LoadViewState event. See this page:
http://www.15seconds.com/issue/020102.htm

Basically, what you *were* doing in overriding the restored view state
value by setting visibility = false *after* the viewstate was restored
properly. So pUpload visibility was always being restored properly by
viewstate, but you were always setting it to false right after that
(LoadViewState event occurs when you add pUpload to the Controls
collection - controls play catchup on lifecycle events when added to a
preexisting control tree). But when you set it to false *before*
adding it to the controls collection you gave a chance for viewstate to
be restored to it properly, since you stopped overriding it right after
that.

Make sense? Basically this ASP.NET stuff is a lot more complicated
than a lot of ppl say it is ;).

-Sam
 

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,770
Messages
2,569,584
Members
45,078
Latest member
MakersCBDBlood

Latest Threads

Top