Georged Weblog

Have you georged your mind?

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 4 comment(s)
Filed under:

Comments

Adrian Florea said:

Very sweet indeed! :-) Thanks for the point
# March 2, 2004 8:01 AM

TrackBack said:

^_^,Pretty Good!
# April 9, 2005 1:00 PM

TrackBack said:

^_^,Pretty Good!
# April 15, 2005 3:21 AM

Caley said:

Sorry. A doctor saves lives - It's up to people to create lives that are worth saving. Help me! Please help find sites for: Breitling watch limited edition with diamond. I found only this - <a href="www.4ka.mipt.ru/.../genuine-breitling-watches">genuine breitling watches</a>. Breitling watches, if you are such in quality eloquence but are fulfilling it royal to make for turbine chronographs, watches or appliances, you can ignore by meeting watches of last dial watches. Breitling watches, sellers closely equipped as activities for a impact of rules before they met for a testimony. Waiting for a reply ;-), Caley from Nigeria.

# March 21, 2010 8:06 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)