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>localhost< FONT>Host>
<Password />
<Path>/test/default.aspx< FONT>Path>
<Port>80< FONT>Port>
<Query />
<Scheme>http< FONT>Scheme>
<UserName />
< FONT>>
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.