2016-07-28 37 views
5

我有一些反序列化的麻煩。將空XML元素反序列化爲Guid.Empty

<Order> 
    ... 
    <CardNumber /> 
    ... 
</Order> 

如果我使用

<CardNumber>00000000-0000-0000-0000-000000000000</CardNumber> 

它的工作正常,但如果我只使用<CardNumber /> - 對象不是反序列化(

有什麼辦法來反序列化空元素GUID。空?

應該映射此元素的值的屬性:

01在JSON

相同的情況正常運行,而不是使用空元素值

{ 
    "CardNumber": "" 
} 
+1

您是否嘗試過將該類的實例序列化爲XML並檢查結果? –

+1

*你的意思是* object是不是反序列化(*。是否拋出異常?如果是這樣,你可以編輯你的問題以包含該異常的完整'ToString()'輸出,包括消息,異常類型和任何內部異常? – dbc

回答

1

你所看到的例外解釋清楚這個問題:

System.InvalidOperationException occurred 
    Message="There is an error in XML document (3, 3)." 
    InnerException: System.FormatException 
     Message="Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)." 

如前所述,XmlSerializer不支持反序列化的一個空字符串到Guid。因此,你需要做轉換使用替代屬性手動:

[XmlRoot("Order")] 
public class Order 
{ 
    [XmlIgnore] 
    [JsonProperty("CardNumber")] 
    public Guid? CardNumber { get; set; } 

    [XmlElement(ElementName = "CardNumber", IsNullable = true)] 
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)] 
    [JsonIgnore] 
    public string XmlCardNumber 
    { 
     get 
     { 
      if (CardNumber == null) 
       return null; 
      else if (CardNumber.Value == Guid.Empty) 
       return ""; 
      return XmlConvert.ToString(CardNumber.Value); 
     } 
     set 
     { 
      if (value == null) 
       CardNumber = null; 
      else if (string.IsNullOrEmpty(value)) 
       CardNumber = Guid.Empty; 
      else 
       CardNumber = XmlConvert.ToGuid(value); 
     } 
    } 
} 

如果這是你需要有Guid?性能的許多不同類型的做一些事情,你可以提取的替代類型,像這樣:

[XmlType(AnonymousType = true, IncludeInSchema = false)] 
public class XmlGuid 
{ 
    [XmlIgnore] 
    public Guid Guid { get; set; } 

    [XmlText] 
    public string XmlCardNumber 
    { 
     get 
     { 
      if (Guid == Guid.Empty) 
       return null; 
      return XmlConvert.ToString(Guid); 
     } 
     set 
     { 
      if (string.IsNullOrEmpty(value)) 
       Guid = Guid.Empty; 
      else 
       Guid = XmlConvert.ToGuid(value); 
     } 
    } 

    public static implicit operator Guid?(XmlGuid x) 
    { 
     if (x == null) 
      return null; 
     return x.Guid; 

    } 

    public static implicit operator XmlGuid(Guid? g) 
    { 
     if (g == null) 
      return null; 
     return new XmlGuid { Guid = g.Value }; 
    } 

    public static implicit operator Guid(XmlGuid x) 
    { 
     if (x == null) 
      return Guid.Empty; 
     return x.Guid; 

    } 

    public static implicit operator XmlGuid(Guid g) 
    { 
     return new XmlGuid { Guid = g }; 
    } 
} 

而且使用它像:

[XmlRoot("Order")] 
public class Order 
{ 
    [XmlElement(Type = typeof(XmlGuid), ElementName = "CardNumber", IsNullable = true)] 
    [JsonProperty("CardNumber")] 
    public Guid? CardNumber { get; set; } 
} 

在這裏,我以自動的事實XmlElementAttribute.Type性能優勢拿起我爲Guid?定義的implicit conversion來自XmlGuid

+0

感謝您的詳細解釋! – ashpakov

3

空是不一樣的Guid.Empty Guid.Empty。在JSON序列化程序中,您使用空字符串表示空值。

如果您使用XmlSerializer序列化您的課程,您會看到它使用xsi:nil="true"表示空值。

例如:

<Order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <CardNumber xsi:nil="true" /> 
</Order> 
+0

非常感謝! – ashpakov