2009-06-24 78 views
16

我有一個類,我標記爲Serializable,具有Uri屬性。我怎樣才能讓Uri序列化/反序列化而不使用字符串類型的屬性?如何(xml)序列化uri

+1

的標籤建議的XmlSerializer;實際上,你不需要[Serializable] - 這個類型只需要公開。 – 2009-06-24 07:12:03

回答

12

基於答案爲how to serialize 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()); 
    } 
} 

然後你可以使用它像這樣

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

... 
var s = new Settings { Uri = new Uri("http://www.example.com") }; 

而且這將很好地進行序列化和反序列化。

注意:不能使用XmlElement(Type = typeof(...))屬性中的技巧,因爲XmlSerializer首先在原始類型上檢查一個空的默認構造函數。

0

Uri類實現ISerializable接口,所以它應該能夠照顧序列化/反序列化。

+0

嗯,也許是3.5的東西?當我在2中序列化時,我得到一個異常,沒有默認的構造函數。0 – Jeremy 2009-06-24 05:56:14

+4

這是*二進制*序列化;問題(請參見標籤)是關於* xml *序列化的 – 2009-06-24 06:52:22

32

隨着XML序列化,你是有限的 - 這是不一樣多功能(說)一些的BinaryFormatter/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);} 
} 

兩個瀏​​覽的屬性隱藏從視圖中(但它需要對公共API的XmlSerializer使用它)。 XmlIgnore告訴它不要嘗試Uri;和[XmlAttribute(...)](或[XmlElement(...)])告訴它將(de)序列化時重命名UriString

(注意:EditorBrowsable僅適用於代碼的程序集聲明類型外)

1

對於其他誰發現這個問題,誰不喜歡的解決方案,還有另一個更靈活和強大的解決方案。它是實現IXmlSerializable接口。這更困難,但它是值得的。你可以創建任何你想要的xml。最簡單的例子是:

public class Product : IXmlSerializable 
{ 
    public string Code { get; set; } 

    public string Model { get; set; } 

    public string Name { get; set; } 

    public Uri ImageUri { get; set; } 

    public virtual System.Xml.Schema.XmlSchema GetSchema() 
    { 
     throw new NotImplementedException(); 
    } 

    public virtual void ReadXml(XmlReader reader) 
    { 
     reader.MoveToContent(); 
     Code = reader.GetAttribute("Code"); 
     Model = reader.GetAttribute("Model"); 
     Name = reader.GetAttribute("Name"); 
     if (reader.ReadToDescendant("Image") && reader.HasAttributes) 
      ImageUri = new Uri(reader.GetAttribute("Src")); 
    } 

    public virtual void WriteXml(XmlWriter writer) 
    { 
     writer.WriteAttributeString("Code", Code); 
     writer.WriteAttributeString("Model", Model); 
     writer.WriteAttributeString("Name", Name); 
     if (ImageUri != null) 
     { 
      writer.WriteStartElement("Image"); 
      writer.WriteAttributeString("Src", ImageUri.AbsoluteUri); 
      writer.WriteEndElement(); 
     } 
    } 
} 

,你會得到這樣的事情在XML:

<PriceContainer Code="314" Model="PP500" Name="NuTone PurePower PP500 Power Unit"> 
    <Image Src="http://www.thinkvacuums.com/images/nutone-pp500-activac.jpg" /> 
</PriceContainer>