Skip to content

July 16, 2009

Custom XML Serialization of a .NET class

I love serialization — right up to the point where it breaks. I have always found that it’s difficult to get right if the out of the box stuff breaks. However, I may have changed my mind. I had to do some of my own serialization because some of the properties that I was working with in my class didn’t serialize well. After a long and drawn out look at the problem here’s my input:

  1. Implement the IXmlSerializable interface. It contains three methods
  2. GetSchema() has been obsoleted. Just return null. There’s a suggestion that you should use an [XmlSchemaProvider] attribute on your class to communicate the method to be used to return the schema for your Xml serialization. My recommendation is to skip it — if you don’t have to validate your Xml (and I don’t know why you would) you don’t have to have this.
  3. WriteXml() writes the data to an XmlWriter. Use WriteAttributeString(string, string) to write out the attributes you need. You can also write out sub-elements but using attributes is easy enough for non-complex types.
  4. If you need to write out a blob of data in middle of your tag you can use WriteCData() to write the contents of a string to the center of your element tag.
  5. ReadXml() reads the serialized data from an XmlReader. Getting your content out is as simple as doing .MoveToContent() and a set of indexer deferences for attributes (i.e. reader[“myAttributeName”]). Finally if you want to read the inner contents you put into a CData section you can do .ReadString().

That’s all there is to writing your custom Xml Serialization interface. This way you don’t have to worry about the dynamic assemblies.

System.Web.UI.Page.IsPostBack and Is This the First Request

Every once in a while I’m surprised by what I don’t know. I have been developing in ASP.NET for a while and I’ve known about Page.IsPostBack to determine whether this is the first request to the page (thus I need to populate controls). However, I had never realized that there was a scenario where this didn’t work. It doesn’t work when you have another page post to your page. The property sees that it’s a POST HTTP request and says “Hey, it’s a postback!” — of course in the scenario when it’s another page that’s doing the posting this doesn’t work so well. So I put together a simple function to use the referrer to figure that out.

public static bool IsFirstRequestToPage()

{

HttpRequest curReq = HttpContext.Current.Request;

string referer = curReq.Headers[“Referer”];

if (string.IsNullOrEmpty(referer)) // not present – should be present on postback

{

return (true);

}

else

{

// Is referrer current page?

Uri curPage = curReq.Url;

Uri refPage = new Uri(referer);

if (Uri.Compare(curPage, refPage,

UriComponents.SchemeAndServer |

UriComponents.Path,

UriFormat.UriEscaped,

StringComparison.InvariantCultureIgnoreCase) == 0)

{

// Same referrer (i.e. postback)

return false;

}

else

{

// Different referer

return true;

}

}

}

Of course, using the referer header is bad because there are scenarios where it won’t be transmitted and some browsers that won’t transmit it, etc., but in my case it works well enough.

Recent Posts

Public Speaking