0

I want to handle the datetime during deserialize. If xml has no node or empty value then I need to set the value to default value of datetime min value or max value based on i have set. So problem here is if xml has startdate with empty value like <startdate></startdate> then i get null instead of DateTime.MinValue. Similarly i may have some other node such as enddate which requires DateTime.MaxValue as default value. If i don't pass the tag startdate then I am getting Minvalue which is expected. So how I can handle for empty tags. I need to get Date Minvalue in case of empty tag as well.

public static void Main()
{
    Program t = new Program();
        
        t.DeserializeObject("<OrderedItem><startdate>20210125</startdate><enddate>20210324</enddate></OrderedItem>");
        t.DeserializeObject("<OrderedItem></OrderedItem>");
        t.DeserializeObject("<OrderedItem><startdate></startdate><enddate></enddate></OrderedItem>"); //In this case i am getting issue, Output will not have default Min and Max Values
}

  private void DeserializeObject(string testData)
    {
        // Create an instance of the XmlSerializer.
        XmlSerializer serializer =
        new XmlSerializer(typeof(OrderedItem));

        // Declare an object variable of the type to be deserialized.
        OrderedItem i;
        using (TextReader reader = new StringReader(testData))
        {
            i = (OrderedItem)serializer.Deserialize(reader);
        }
    Console.Write("Start date is "+i.Startdate.Date+"\n");
    Console.Write("End date is "+i.Enddate.Date+"\n\n");
    
    }

public class OrderedItem
{
    
    [XmlElement(ElementName = "startdate")]
    [DefaultValue(typeof(DateTime), "0001-01-01T00:00:00")]
 public CustomDateTime Startdate { 
        get; 
        set;
    } = new CustomDateTime { Date = DateTime.MinValue };

 [XmlElement(ElementName = "enddate")]
    [DefaultValue(typeof(DateTime), "9999-12-31T00:00:00")]
 public CustomDateTime Enddate { 
        get; 
        set;
    } = new CustomDateTime { Date = DateTime.MaxValue };
}

And in my CustomDateTime I am using IXmlSerializable and below is portion of code

public class CustomDateTime : IXmlSerializable, IComparable, IComparable<DateTime>
{
    static string[] formats = new string[] { "yyyyMMdd", "yyyy-MM-dd" };
    [XmlIgnore]
    public DateTime? Date
    {
        get;
        set;
    }
   // here i have CompareTo and other methods which implements interface
public void ReadXml(XmlReader reader)
    {
        string input = reader.ReadString();

        DateTime inputDate;
        if (DateTime.TryParseExact(input, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out inputDate))
        {
            Date = inputDate;
        }
        else
        {
            Date = null;
        }
        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        if (Date != null)
        {
            writer.WriteString(Date.Value.ToString("yyyyMMdd"));
        }
    }
}

Actual Output

Start date is 1/25/2021 12:00:00 AM End date is 3/24/2021 12:00:00 AM

Start date is 1/1/0001 12:00:00 AM End date is 12/31/9999 11:59:59 PM

Start date is End date is

Expected Output

Start date is 1/25/2021 12:00:00 AM End date is 3/24/2021 12:00:00 AM

Start date is 1/1/0001 12:00:00 AM End date is 12/31/9999 11:59:59 PM

Start date is 1/1/0001 12:00:00 AM End date is 12/31/9999 11:59:59 PM

Fiddle:https://dotnetfiddle.net/qv7sjP

I thought I can add defaultvalue attribute like [DefaultValue(typeof(DateTime), "0001-01-01T00:00:00")] or [DefaultValue(typeof(DateTime), "9999-12-31T00:00:00")] as required to property Startdate and Enddate and read this in ReadXml method and then set Date property in ReadXml method when tag not present(else block). I am not sure how i can read this and handle it. Also i am not sure is this appropriate solution

1 Answer 1

1

Try following :

    public class OrderedItem
    {
        private DateTime _Startdate = new DateTime();
        [XmlElement(ElementName = "startdate")]
        public DateTime Startdate { 
            get{ return _Startdate;} 
            set{ _Startdate = value;}
        }

        private DateTime _Enddate = new DateTime();
        [XmlElement(ElementName = "enddate")]
        public DateTime Enddate
        {
            get { return _Enddate; }
            set { _Enddate = value; }
        }
    }
Sign up to request clarification or add additional context in comments.

9 Comments

I am using CustomDate class not Datetime. But as per your suggestions i modified my code using CustomDate and it won't resolve the original issue. See fiddle for reference dotnetfiddle.net/K5Z9gR . I have created this based on the suggestions you provided, Please let me know if i am doing anything wrong
I would make the default constructor in CustomDateTime new DateTime : public CustomDateTime() { Date = new DateTime();}
Ok. But I don't want current datetime to be default value. I want either DateTime minvalue or maxvalue based on my property. I have specified them in question too. In the code shared in question i have taken 3 sample XML inputs. I am facing issue in 3 rd case
new DataTime() is 1/1/01. public CustomDateTime(DateTime date) { Date = date;}
Ok. If I do this. both start and end date will.have same default date of 1/1/01. But I wanted to set different default (mentioned in question and I was trying min and max values). Also my issue happens when XML is having empty value node. So this is happening after the value is set in constructor. So that value will be overwritten with empty in my case. From the fiddle shared in question i am able to reproduce the issue. I feel you have not understood my original issue mentioned in question. Let me know If i am missing something or if I need to rewrite the question appropriately.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.