I created a really simple control that contains a list of filter option controls in much the same way that a listbox has a list of listitems.
I’m having some trouble tring to get it to serialize in to viewstate as the serializer appears to be trying to serialize the base class properties and basically i end up with errors like – cannot serialize property “page” What do you think is my problem?
The Code:
[Serializable]
public class FilterOption : Control, ISerializable
{
public event EventHandler Checkchanged;
CheckBox _chk = new CheckBox();
Label _lbl = new Label();
public string Text
{
get { return _lbl.Text; }
set { _lbl.Text = value; }
}
public bool Checked
{
get { return _chk.Checked; }
set { _chk.Checked = value; }
}
public FilterOption()
{
Controls.Add(new LiteralControl("<li>"));
_chk.AutoPostBack = true;
_chk.CssClass = "checkbox";
Controls.Add(_chk);
Controls.Add(_lbl);
_chk.CheckedChanged += new EventHandler(_chk_CheckedChanged);
Controls.Add(new LiteralControl("</li>"));
}
public FilterOption(string Text, bool Checked)
{
Controls.Add(new LiteralControl("<li>"));
_chk.CssClass = "checkbox";
_lbl.Text = Text;
_chk.Checked = Checked;
Controls.Add(_chk);
Controls.Add(_lbl);
_chk.CheckedChanged += new EventHandler(_chk_CheckedChanged);
Controls.Add(new LiteralControl("</li>"));
}
public FilterOption(SerializationInfo info, StreamingContext context)
{
Controls.Add(new LiteralControl("<li>"));
_chk.CssClass = "checkbox";
_lbl.Text = (string)info.GetValue("Text", typeof(string));
_chk.Checked = (bool)info.GetValue("Text", typeof(bool));
Controls.Add(_chk);
Controls.Add(_lbl);
_chk.CheckedChanged += new EventHandler(_chk_CheckedChanged);
Controls.Add(new LiteralControl("</li>"));
}
void _chk_CheckedChanged(object sender, EventArgs e)
{
if (Checkchanged != null)
Checkchanged(this, new EventArgs());
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if(info == null)
throw new System.ArgumentNullException("info");
info.AddValue("Text", _lbl.Text);
info.AddValue("Checked", _chk.Checked);
}
}
I literally only need to serialize the properties added to the serialization info in the GetObjectData method.
I’m using the following code to perform the serialization …
List<FilterOption> options = new List<FilterOption>();
... add some items to the collection ...
StringWriter writer = new StringWriter();
XmlSerializer ser = new XmlSerializer(typeof(List<FilterOption>));
ser.Serialize(writer, options);
ViewState["Options"] = writer.ToString();
Oh yeh … i forgot to add … i got the information from here …
http://msdn.microsoft.com/en-us/library/ms973893.aspx
(in case it matters)
…
Thx Wardy
Apparently you cannot serialize a type that inherits a non serializable type even ifyou do not wish to serialize the non-serializable properties of your derived type.
I think this should be classed as a bug since the who point of interfaces like ISerializable is to specify exactly what it is you inted to serialize by manually implementing the method that handles the serialization.
In any case the solution to my particular scenario was to not bother serializing at all and simply save the information of interest in to viewstate which would then be reused on postbacks to rebuild controls in the exact same state ready for the page based postback events to occur.
Shame this isnt better documented somewhere because although microsoft does document the SaveViewState and LoadViewState methods of the page lifecycle they are very vague about how these events might be used, i’m guessing they are hoping someone in the community might provide an example.
I would post my code but its a nasty hack to get everything working so i don’t thing it should be mainstream msdn code.
Ok for a small internal app though 🙂