Georged Weblog

Have you georged your mind?

November 2003 - Posts

Books upgrade

I was looking at Programming ASP.NET, Second Edition on Amazon and suddenly the question came up:

Why do we always expect software vendors to offer upgrades for their products but no one expects that for books? Is there some economical rationale I'm missing? How cool would it be to walk into a bookstore holding the first edition and to hear "Oh, yes, sir, this mighty book you've got in your hands qualifies you for an upgrade discount of 40%".

Posted: Nov 30 2003, 01:55 AM by georged | with 2 comment(s)
Filed under:
XmlPleaseIgnore

There is a handy class UriBuilder which, unlike Uri, allows full read-write access to all the components of Uri. However, problems started when I tried to serialise it using XmlSerializer. The following code:

using System;
using System.Collections;
using System.Xml;
using System.Xml.Serialization;
public class XmlPleaseIgnore
{
    public static void Main()
    {
        UriBuilder b = new UriBuilder("http", "localhost", 80, "/test/default.aspx");
        XmlSerializer x = new XmlSerializer(b.GetType());
        x.Serialize(Console.Out, b);
    }
}

quickly produced this:

Unhandled Exception: System.InvalidOperationException: There was an error reflecting type 'System.UriBuilder'. ---> System.InvalidOperationException: System.Uri cannot be serialized because it does not have a default public constructor.

A bit of digging revealed that UriBuilder.Serialize method

...converts the public fields and read/write properties of an object into XML. It does not convert methods, indexers, private fields, or read-only properties. To serialize all of an object's fields and properties, both public and private, use the BinaryFormatter.

And, of course, Uri property of UriBuilder is read-only property and, to make the matter worse, it does not have public default constructor. If it were my class I would apply XmlIgnore attribute to the member and that would do the trick. As I found, with a bit of code it can be done for external classes as well:

using System;
using System.Collections;
using System.Xml;
using System.Xml.Serialization;
public class XmlPleaseIgnore
{
    public static void Main()
    {
        // add XmlIgnore attribute and attach it to Uri member of UriBuilder class
        XmlAttributes attrs = new XmlAttributes();
        attrs.XmlIgnore = true;
        XmlAttributeOverrides over = new XmlAttributeOverrides();
        over.Add( typeof(UriBuilder), "Uri", attrs);
        
        UriBuilder b = new UriBuilder("http", "localhost", 80, "/test/default.aspx");
        XmlSerializer x = new XmlSerializer(b.GetType(), over); // override attributes
        x.Serialize(Console.Out, b);
    }
}
And here is the output:
xml version="1.0" encoding="utf-8" ?>
<UriBuilder
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Fragment />
<Host>localhostHost>
<Password />
<Path>/test/default.aspxPath>
<Port>80Port>
<Query />
<Scheme>httpScheme>
<UserName />
> 

Note that attribute is applied to a member of a class and therefore I can also serialise my own classes which have UriBuilder as a member variable.

Sweet.

Posted: Nov 06 2003, 12:05 PM by georged | with 3 comment(s)
Filed under:
More Posts