如何(xml)序列化uri

Jer*_*emy 16 .net c# xml-serialization

我有一个我标记为Serializable的类,具有Uri属性.如何在不创建string类型属性的情况下让Uri序列化/反序列化?

Mar*_*ell 32

使用xml序列化程序,你是有限的 - 它不像(例如)一些二进制格式化程序/ ISerializable选项那样通用.一个常见的技巧是获得序列化的第二个属性:

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

[XmlAttribute("uri")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public string UriString {
    get {return Uri == null ? null : Uri.ToString();}
    set {Uri = value == null ? null : new Uri(value);}
}
Run Code Online (Sandbox Code Playgroud)

两个可浏览的属性将其隐藏在视图中(但它需要在公共API上XmlSerializer才能使用它).该XmlIgnore告诉它不要尝试Uri; 并且[XmlAttribute(...)](或[XmlElement(...)])告诉它UriString在(de)序列化时重命名.

(注意,EditorBrowsable仅适用于声明类型的程序集外部的代码)


Chr*_*Wue 12

基于如何序列化TimeSpan的答案之一,我最终得到了这对我很有效,并且不需要额外的属性:

public class XmlUri : IXmlSerializable
{
    private Uri _Value;

    public XmlUri() { }
    public XmlUri(Uri source) { _Value = source; }

    public static implicit operator Uri(XmlUri o)
    {
        return o == null ? null : o._Value;
    }

    public static implicit operator XmlUri(Uri o)
    {
        return o == null ? null : new XmlUri(o);
    }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        _Value = new Uri(reader.ReadElementContentAsString());
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteValue(_Value.ToString());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它

public class Settings
{
     public XmlUri Uri { get; set; }
}

...
var s = new Settings { Uri = new Uri("http://www.example.com") };
Run Code Online (Sandbox Code Playgroud)

它将很好地序列化和反序列化.

注意:不能使用XmlElement(Type = typeof(...))上面链接问题中另一个答案中给出的属性作为XmlSerializer原始类型首先检查空默认构造函数的技巧.