0

I'm sending some data from a local application to another one (ASP.NET MVC). The data is an array of DTOs. I am testing this on my local machine.

The local application is a Web Forms and is sending the data using a service. I do not use JsonResult.

The serialzed DTO is sent correctly, but the dates are deserialized incorrectly on the MVC side, being a day behind then the ones sent.

The DTO class looks like this:


    [DataContract]
    public class ProjectInfoDto
    {
        [DataMember]
        public long ProjectId { get; set; }

        [DataMember]
        public string ProjcetCode { get; set; }

        [DataMember]
        public DateTime BeginDate { get; set; }

        [DataMember]
        public DateTime FinalDate { get; set; }
    }

I am serializing the data using the below method:

public static string JsonSerialize<T>(T obj)
{
    var serializer = new DataContractJsonSerializer(obj.GetType());
    var ms = new MemoryStream();
    serializer.WriteObject(ms, obj);
    string retVal = Encoding.Default.GetString(ms.ToArray());
    ms.Dispose();
    return retVal;
}

The JSON sent to the MVC application looks like this (with correct dates):


{"ProjectId":"222","ProjcetCode":"OP9089","BeginDate":"/Date(1461790800000+0300)/","FinalDate":"/Date(1557435600000+0300)/" }

The method receiving the data looks like this:

public ActionResult GetProjectData(ProjectInfoDto[] info) {...}

The original dates are (from the database):

BeginDate -> 2016-04-28 00:00:00.000

FinalDate -> 2019-05-10 00:00:00.000

The dates on the MVC side when looking at the received array:

BeginDate -> 2016-04-27 00:00:00.000

FinalDate -> 2019-05-09 00:00:00.000

I don't know why the dates are a day behind when received.

CristisS
  • 1,103
  • 1
  • 12
  • 31
  • 1
    Could you include some sample data and the code involved? Help us help you. – n8wrl Nov 02 '17 at 18:25
  • You are probably serializing/deserializing them in different time zones. – JuanR Nov 02 '17 at 18:25
  • Please post more code. How are you sending them? Is it a call to a page? A web service? – JuanR Nov 02 '17 at 18:27
  • Added more code... had problems with the editor. Thanks – CristisS Nov 02 '17 at 18:27
  • Not enough. We need to see how you send it and how you receive it. – JuanR Nov 02 '17 at 18:28
  • 2
    To make a long story short, JSON does not account for dates. You are letting the model binder deserialize it and it obviously doesn't work very well. If you intend to continue to use JSON, I would suggest you make the field a `string` on the DTO and set it to a known format, then deserialize it manually on the MVC application. I will mark this question as a duplicate of the one that explains this. – JuanR Nov 02 '17 at 18:40
  • 1
    Possible duplicate of [ASP.NET MVC JsonResult Date Format](https://stackoverflow.com/questions/726334/asp-net-mvc-jsonresult-date-format) – JuanR Nov 02 '17 at 18:40
  • I'll take a look at the possible duplicate and give it a try. Will comment tomorrow. Thanks! – CristisS Nov 02 '17 at 18:45
  • 1
    It's usually a good idea to use an ISO-8601 formatted datetime when passing a date around to different machines. – Jasen Nov 02 '17 at 18:48

1 Answers1

0

I found a suggestion in this question Is there a way to override how DataContractJsonSerializer serializes Dates?.

The answer in the question suggests creating an instance method and decorate it using the

[OnSerializing]
attribute. This will allow custom serialization for certain attributes.

Full code below:



[DataContract]
public class ProjectInfoDto
{
    [DataMember(Name = "BeginDate")]
    private string beginDate;

    [DataMember(Name = "ExecutieDataFinal")]
    private string finalDate;

    [DataMember]
    public long ProjectId { get; set; }

    [DataMember]
    public string ProjcetCode { get; set; }

    public DateTime BeginDate { get; set; }

    public DateTime FinalDate { get; set; }

    [OnSerializing]
    void OnSerializing(StreamingContext context)
    {
        beginDate = BeginDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
        finalDate = FinalDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
    }
}

The idea is to leave the DateTime properties intact, and use the private string fields for the serialzation. In the OnSerializing method, you convert the DateTime properties to the required format. As per the suggestions in the comments to my question, I used the ISO-8601 format ("yyyy-MM-dd").

CristisS
  • 1,103
  • 1
  • 12
  • 31