I am experiencing issues with a WCF REST service. The wire object that I try to return has certain properties not set, resulting in DateTime.MinValue for properties of type DateTime. The service returns an empty document (with HTTP status 200 ???). When I try to call JSON serialization myself, the exception that is thrown is:
SerializationException: DateTime values that are greater than DateTime.MaxValue or smaller than DateTime.MinValue when converted to UTC cannot be serialized to JSON.
This can be reproduced by running the following code in a console app:
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(DateTime));
MemoryStream m = new MemoryStream();
DateTime dt = DateTime.MinValue;
// throws SerializationException in my timezone
ser.WriteObject(m, dt);
string json = Encoding.ASCII.GetString(m.GetBuffer());
Console.WriteLine(json);
Why is this behaviour? I think it is related to my timezone (GMT+1). As DateTime.MinValue is default(DateTime), I would expect that this can be serialized without problems.
Any tips on how to make my REST service behave? I don't want to change my DataContract.
The main problem is DateTime.MinValue
has DateTimeKind.Unspecified
kind. It is defined as:
MinValue = new DateTime(0L, DateTimeKind.Unspecified);
But this is not a real problem, this definition leads to problem during serialization. JSON DateTime serialization done through:
System.Runtime.Serialization.Json.JsonWriterDelegator.WriteDateTime(DateTime value)
Unfortunately it is defined as:
...
if (value.Kind != DateTimeKind.Utc)
{
long num = value.Ticks - TimeZone.CurrentTimeZone.GetUtcOffset(value).Ticks;
if ((num > DateTime.MaxValue.Ticks) || (num < DateTime.MinValue.Ticks))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString("JsonDateTimeOutOfRange"), new ArgumentOutOfRangeException("value")));
}
}
...
So it doesn't take into account Unspecified
and treats it as Local
. To avoid this situation you can define your own constant:
MinValueUtc = new DateTime(0L, DateTimeKind.Utc);
or
MinValueUtc = DateTime.MinValue.ToUniversalTime();
It looks weird of course, but it helps.
Try to add this on any DateTime Member
[DataMember(IsRequired = false, EmitDefaultValue = false)]
Most of these erros happens because the default value of the datetime
is DateTime.MinValue
which is from year of 1 and the JSON serialization is from year 1970.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With