5

I am using Newtonsoft.Json to deserialize an object. And I am getting the following Exception:

Newtonsoft.Json.JsonSerializationException
  HResult=0x80131500
  Message=Error converting value {null} to type 'System.DateTime'. Path 'StartDate', line 1, position 62.
  Source=Newtonsoft.Json
  
Inner Exception 1:
InvalidCastException: Null object cannot be converted to a value type.

The original json has null values:

{
  "StartDate": null,
  "EndDate": null
}

But I am supplying settings to JsonConvert.DeserializeObject to avoid the null values, as mentioned here and here:

var convertedMessage = JsonConvert.DeserializeObject<T>(
                Encoding.UTF8.GetString(message.Body),
                new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

Any idea why it keeps throwing this exception?

The code is running fine if an actual date value is provided.

More background on the code, the message.Body is the body of a message received through a service bus (class Microsoft.Azure.ServiceBus.Message). And applying the GetString method to it returns the same string as in the message sent.

A runnable sample of the code:

using System;
using System.Text;
using Microsoft.Azure.ServiceBus;
using Newtonsoft.Json;


namespace ConsoleApp1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine(DeserializeJsonMessage<SampleMessage>(
                new Message(Encoding.UTF8.GetBytes("{\"Id\":\"d2725a22-fdfb-48df-8871-54bbcb1a95b4\",\"StartDate\":null,\"EndDate\":null}"))
                ));
        }

        public static T DeserializeJsonMessage<T>(Message message) where T : IMessage
        {
            var convertedMessage = JsonConvert.DeserializeObject<T>(
                Encoding.UTF8.GetString(message.Body),
                new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

            return convertedMessage;
        }
    }

    public interface IMessage
    {
        Guid Id { get; set; }
        DateTime StartDate { get; set; }
        DateTime EndDate { get; set; }
    }

    public class SampleMessage : IMessage
    {
        public Guid Id { get; set; }
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }

        public SampleMessage(Guid id, DateTime startDate, DateTime endDate)
        {
            Id = id;
            StartDate = startDate;
            EndDate = endDate;
        }

        public override string ToString()
        {
            return JsonConvert.SerializeObject(this);
        }
    }
}

0

1 Answer 1

3

Did you try to set Start/End Date as nullable object and implement a Interface by them?

public class SampleMessage : IMessage
{
    public Guid Id { get; set; }
    public DateTime? StartDate { get; set; }
    public DateTime? EndDate { get; set; }

    public SampleMessage(Guid id, DateTime? startDate, DateTime? endDate)
    {
        Id = id;
        StartDate = startDate;
        EndDate = endDate;
    }

    public override string ToString()
    {
        return JsonConvert.SerializeObject(this);
    }

    DateTime IMessage.StartDate { get => this.StartDate ?? DateTime.Now; set => this.StartDate = value; }
    DateTime IMessage.EndDate { get => this.EndDate ?? DateTime.Now; set => this.EndDate = value; }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Tried that before and the code throws the same exception.
I missed constructor - now should be working (works on yours sample)
Nice! Thanks. I forgot that I also needed to update the constructor. But then, why is the JsonSerializer settings (NullValueHandling.Ignore) not working?
Rather than DateTime.Now I would suggest using default(DateTime) to represent an uninitialized value.
@Endovelicvs - It seems as though NullValueHandling.Ignore does not apply for constructor arguments, since a value for the constructor argument is required to construct and deserialize the object. Declaring the constructor argument as a nullable solves the problem. Or you could make a private constructor with nullable arguments and mark it with [JsonConstructor].

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.