简体   繁体   中英

DateTime System.FormatException in XML Serializable c#

I am trying to read the data from an XML.
Every thing is good except for a date field. When ever the date field is null , I am getting Exception

System.FormatException: The string '' is not a valid AllXsd value.
at System.Xml.Schema.XsdDateTime..ctor(String text, XsdDateTimeFlags kinds) at System.Xml.XmlConvert.ToDateTime(String s, XmlDateTimeSerializationMode dateTimeOption) at System.Xml.Serialization.XmlSerializationReader.ToDateTime(String value)

Here is my XML

<TRANSACTION>
    <TRANSACTION_ID></TRANSACTION_ID>
    <MERCHANT_ACC_NO>02700701354375000964</MERCHANT_ACC_NO>
    <TXN_STATUS>F</TXN_STATUS>
    <TXN_SIGNATURE777779</TXN_SIGNATURE>
    <TXN_SIGNATURE2>877888C</TXN_SIGNATURE2>
    <TRAN_DATE></TRAN_DATE>
    <MERCHANT_TRANID>151019OHOOZS1</MERCHANT_TRANID>
    <RESPONSE_CODE>3009</RESPONSE_CODE>
    <RESPONSE_DESC>Unable to find the transaction record!</RESPONSE_DESC>
    <AUTH_ID></AUTH_ID>
    <AUTH_DATE></AUTH_DATE>
    <CAPTURE_DATE></CAPTURE_DATE>
    <SALES_DATE></SALES_DATE>
    <VOID_REV_DATE></VOID_REV_DATE>
  </TRANSACTION>
</TRANSACTION_RESPONSE>

Now my class

[Serializable]
    public class MaybankeBPGResponse
    {
        [XmlElement("TRANSACTION_ID")]
        public string MaybankeBPGTxnId { get; set; }

        [XmlAttribute("MERCHANT_TRANID")]
        public string MerchantTxnId { get; set; }

        [DefaultValueAttribute(typeof(System.DateTime), "1901-01-01")]
        [XmlElement("TRAN_DATE")]
        public DateTime? AuthDate { get; set; }

        [XmlElement("RESPONSE_CODE")]
        public string ResponseCode { get; set; }
}

I suspect the AuthDate element is causing the problem when the XML value is null.

Could you use an intermediate property like this?

[XmlElement("TRAN_DATE")]
public string? stringAuthDate { get; set; }

[XmlIgnore]
public DateTime AuthDate
{
  get
  {
    DateTime dt;
    if (stringAuthDate.HasValue && DateTime.TryParse(stringAuthDate.Value, out dt))
      return dt;
    else
      return DateTime.MinValue;
  }
  set
  {
    stringAuthDate = value.ToShortDateString();   
  }
}

The problem is the XML is invalid, at least as far as data types go. As the error message indicates the date in the XML is an empty string. The xml fragment indicates the value of the elemtn AUTH_DATE is an empty string, not a null value. If you want a null value, then you need .

You have a couple of solutions, the easiest and dirtiest being: - Add a property used to capture the data as a raw string - Modify the existing property to parse the data from this new property

[Serializable]
public class MaybankeBPGResponse
{
    [XmlElement("TRANSACTION_ID")]
    public string MaybankeBPGTxnId { get; set; }

    [XmlAttribute("MERCHANT_TRANID")]
    public string MerchantTxnId { get; set; }

    [DefaultValueAttribute(typeof(System.DateTime), "1901-01-01")]
    [XmlElement("TRAN_DATE")]
    [EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
    [System.ComponentModel.BrowsableAttribute(false)]
    public DateTime? AuthDateForSerialization { get; set; }

    public DateTime? AuthDate { 
        get {
            return String.IsNullOrEmpty(AuthDateForSerialization) ? null : DateTime.ParseExact(AuthDateForSerialization, "yyyy-MM-dd", CultureInfo.InvariantCulture);
        }
        set {
            AuthDateForSerialization = value.HasValue ? value.Value.ToString("yyyy-MM-dd") : String.Empty;
        }
    }

    [XmlElement("RESPONSE_CODE")]
    public string ResponseCode { get; set; }
}

Thank you all for the feedback.
Based on the comments and answers provided, i added a new property to capture the TRAN_DATE response as a string and convert it to date in the code . here is the snippet

  [Serializable]
    public class MaybankeBPGResponse
   { 
    public DateTime? AuthDate { get; set; }

    [XmlElement("TRAN_DATE")]
     public string AuthDateXML { get; set; }

   }

In the reading part , following modification is added

using (TextReader xmlreader = new StringReader(responseData))
 {
   QueryResponse value = (QueryResponse)serializer.Deserialize(xmlreader);
   result = value.transaction;

  DateTime autDate = DateTime.MinValue;

  if (!string.IsNullOrEmpty(result.AuthDateXML))
   {
    DateTime.TryParseExact(result.AuthDateXML, "dd-MM-yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out autDate);
     result.AuthDate = autDate;
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM