System.Uri实现了ISerializable,但是给出了错误?

时间:2009-10-20 11:46:41

标签: .net xml-serialization

  

可能重复:
  How to (xml) serialize a uri

据我所知Uri实现了ISerializable,但在使用时抛出错误:

XmlSerializer xs = new XmlSerializer(typeof(Server));
xs.Serialize(Console.Out, new Server { Name = "test", URI = new Uri("http://localhost/") });

public class Server
{
    public string Name { get; set; }
    public Uri URI { get; set; }
}

如果Uri类型更改为string,则工作正常。

任何人都知道罪魁祸首是什么?


Anton Gogolev提出的解决方案
public class Server
{
    public string Name { get; set; }

    [XmlIgnore()]
    public Uri Uri; 

    [XmlElement("URI")]
    public string _URI // Unfortunately this has to be public to be xml serialized.
    { 
        get { return Uri.ToString(); }
        set { Uri = new Uri(value); }
    }
}

(感谢 SLaks 也指出我方法的落后......)

这会产生XML输出:

<Server>
    <URI>http://localhost/</URI>
    <Name>test</Name>
</Server>

我在这里重写了它,所以代码是可见的。

4 个答案:

答案 0 :(得分:9)

为了序列化为XML,Uri类应该有一个无参数构造函数,它没有:Uri被设计为不可变的。老实说,如果没有无参数构造函数,我无法理解为什么它不能序列化

要绕过此问题,请将URI属性类型更改为string,或添加一个名为_URI的属性,将URI标记为XmlIgnoreAttribute并重写它get方法为get { return new Uri(_URI); }

答案 1 :(得分:9)

实际上,最好的解决方案是反过来 - 将值存储在Uri属性中并使用字符串访问它。

例如:

public class Server
{
    public string Name { get; set; }

    [XmlIgnore]
    public Uri Uri { get; set; }

    [XmlElement("URI")]
    public string UriString { 
        get { return Uri.ToString(); }
        set { Uri = new Uri(value); } 
    }
}

这样,就不可能将它设置为无效的Uri(在你的代码中会在属性getter中抛出异常)。此外,要遵循标准.Net套管指南,应该将该属性称为Uri,而不是URI

答案 2 :(得分:2)

您将二进制序列化与XML序列化混淆。

XML序列化是一个非常简单的过程,可以将字段值保存并保存到新对象中。

二进制序列化功能更强大,允许对象控制序列化行为。 Uri实现的ISerializable接口仅用于二进制序列化。

答案 3 :(得分:0)

内部例外说:

System.Uri无法序列化,因为它没有无参数构造函数。

简单的答案是你无法将其序列化为xml。