I have a composite control that contains a ListBox child control. On postback, the items for the ListBox disappear. I have a property for the ListBox that initializes it, and I add it to the controls collection in CreateChildControls. Am I doing something wrong? Do I need to be doing something else to properly handle the viewstate of this ListBox?
R – How to properly handle the viewstate of a child control within a composite control
asp.netcomposite-controlsviewstate
Related Solutions
I think you are attacking it from the wrong angle by trying to encode all posted data.
Note that a "<
" could also come from other outside sources, like a database field, a configuration, a file, a feed and so on.
Furthermore, "<
" is not inherently dangerous. It's only dangerous in a specific context: when writing strings that haven't been encoded to HTML output (because of XSS).
In other contexts different sub-strings are dangerous, for example, if you write an user-provided URL into a link, the sub-string "javascript:
" may be dangerous. The single quote character on the other hand is dangerous when interpolating strings in SQL queries, but perfectly safe if it is a part of a name submitted from a form or read from a database field.
The bottom line is: you can't filter random input for dangerous characters, because any character may be dangerous under the right circumstances. You should encode at the point where some specific characters may become dangerous because they cross into a different sub-language where they have special meaning. When you write a string to HTML, you should encode characters that have special meaning in HTML, using Server.HtmlEncode. If you pass a string to a dynamic SQL statement, you should encode different characters (or better, let the framework do it for you by using prepared statements or the like)..
When you are sure you HTML-encode everywhere you pass strings to HTML, then set ValidateRequest="false"
in the <%@ Page ... %>
directive in your .aspx
file(s).
In .NET 4 you may need to do a little more. Sometimes it's necessary to also add <httpRuntime requestValidationMode="2.0" />
to web.config (reference).
There is not enough information. When do you create controls? When do you add them to the Controls collection? What is condition and does it change on postback?
The viewstate is saved automatically at the end of the page cycle (postback or not) given that controls are added at the right time.
If you are adding controls later on, in some event after all initialization has been done, then it is too late.
Update
Without code it is difficult to guess where the break down occurs. Let's examine a Repeater with custom template which could load controls base on some condition. This sample is working, but it would fail if the template assignment was done on Page_Load. Is this something similar to your situation?
Form:
<div>
<asp:Repeater ID="repeater" runat="server" />
<asp:Button ID="submitButton" runat="server" Text="Submit" onclick="submitButton_Click" />
<asp:Button ID="postButton" runat="server" Text="PostBack" />
</div>
Code:
public partial class _Default : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
repeater.ItemTemplate = new MyTemplate();
}
protected void Page_Load(object sender, EventArgs e)
{
//however, if I was to move repeater.ItemTemplate = new MyTemplate() here
//it would not reload the view state
if (!IsPostBack)
{
repeater.DataSource = new int[] { 1, 2, 3, 4, 5 };
repeater.DataBind();
}
}
protected void submitButton_Click(object sender, EventArgs e)
{
submitButton.Text = "Do it again";
}
}
public class MyTemplate : IBindableTemplate, INamingContainer
{
#region IBindableTemplate Members
public System.Collections.Specialized.IOrderedDictionary ExtractValues(Control container)
{
OrderedDictionary dictionary = new OrderedDictionary();
return dictionary;
}
#endregion
#region ITemplate Members
public void InstantiateIn(Control container)
{
Label label = new Label();
label.Text = "Label";
container.Controls.Add(label);
TextBox textbox = new TextBox();
container.Controls.Add(textbox);
}
#endregion
}
Best Answer
Be sure to add your control to the parent before you add listitems or databind. Otherwise, your composite control won't track viewstate on your ListBox's listitems.
Here's a more thorough explanation: http://scottonwriting.net/sowblog/posts/2129.aspx.