Deserialize empty XML element as Guid.Empty

后端 未结 2 770
猫巷女王i
猫巷女王i 2021-01-18 19:47

I have some troubles with deserializing.


    ...
    
    ...

If I use

&l         


        
2条回答
  •  [愿得一人]
    2021-01-18 20:10

    The exception you are seeing explains the problem clearly:

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

    As stated, XmlSerializer does not support deserializing an empty string to a Guid. Thus you will need to do the conversion manually using a surrogate property:

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

    If this is something you need to do in many different types that have Guid? properties, you can extract a surrogate type like so:

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

    And use it like:

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

    Here I am taking advantage of the fact that the XmlElementAttribute.Type property automatically picks up the implicit conversion I defined for Guid? from and to XmlGuid.

提交回复
热议问题