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

Cia*_*tic 10 .net xml-serialization

可能重复:
如何(xml)序列化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; }
}
Run Code Online (Sandbox Code Playgroud)

如果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); }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

这会产生XML输出:

<Server>
    <URI>http://localhost/</URI>
    <Name>test</Name>
</Server>
Run Code Online (Sandbox Code Playgroud)

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

Ant*_*lev 9

为了序列化为XML,Uri类应该有一个无参数的构造函数,它没有:Uri设计为不可变的.老实说,我不明白为什么没有无参数构造函数就无法序列化.

为了避免这个,要么改变URI属性类型string,或增加一个属性调用_URI,标记URIXmlIgnoreAttribute和重写它的get方法get { return new Uri(_URI); }.


SLa*_*aks 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); } 
    }
}
Run Code Online (Sandbox Code Playgroud)

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