2016-07-28 9 views
5

Ich habe einige Probleme mit der Deserialisierung.Deserialisieren leeres XML-Element als Guid.Empty

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

Wenn ich

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

es normal funktioniert, aber im Fall, wenn ich nur <CardNumber /> verwenden - Objekt nicht Deserialisieren (

Gibt es eine Möglichkeit leeres Element als Guid deserialisieren. Leer?

Die Eigenschaft, die mit dem Wert dieses Elements verknüpft werden soll:

[XmlElement(ElementName = "CardNumber")] 
[JsonProperty("CardNumber")] 
public Guid? CardNumber { get; set; } 

Gleiche Situation in JSON normal funktioniert und verwendet Guid.Empty statt leeren Elementwert

{ 
    "CardNumber": "" 
} 
+1

Haben Sie versucht, eine Instanz dieser Klasse in XML zu serialisieren und das Ergebnis zu überprüfen? –

+1

Was meinst du mit * Objekt wird nicht deserialisiert (*. Wird eine Ausnahme ausgelöst? Wenn ja, kannst du deine Frage so bearbeiten, dass sie die vollständige 'ToString()' - Ausgabe der Ausnahme enthält, einschließlich Nachricht, Ausnahmetyp und jede innere Ausnahme? – dbc

Antwort

1

Die Ausnahme, die Sie sehen werden, erklärt das Problem deutlich:

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)." 

Wie bereits erwähnt, XmlSerializer unterstützt nicht eine leere Zeichenfolge zu einem Guid Deserialisieren. So müssen Sie die Konvertierung manuell mit einem Surrogat-Eigenschaft tun:

[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); 
     } 
    } 
} 

Wenn dies etwas, das Sie in viele verschiedene Arten tun müssen, ist, die Guid? Eigenschaften haben, können Sie einen Ersatztyp wie so extrahieren:

[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 }; 
    } 
} 

Und verwenden sie es mögen:

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

Hier habe ich den Vorteil der Tatsache nehme, dass die XmlElementAttribute.Type Eigenschaft automatisch nimmt die implicit conversion auf, die ich für Guid? von und zu XmlGuid definiert habe.

+0

Danke für die detaillierte Erklärung! – ashpakov

3

Null nicht die gleichen wie Guid.Empty ist. Im JSON-Serializer bezeichnen Sie null mit einer leeren Zeichenfolge.

Wenn Sie Ihre Klasse unter Verwendung XmlSerializer serialisieren, sehen Sie, dass xsi:nil="true" verwendet wird, um einen Nullwert zu bezeichnen.

Zum Beispiel:

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

Vielen Dank! – ashpakov