4

I have a Web API middle layer which consumes an API which exposes a field which carries a timestamp as string (the field is string and it contains a value like "2016-05-31T14:12:45.753Z").

The proxy classes in the middle tier are generated using Visual Studio from Swagger endpoint and under the hood the object is deserialized using Json.NET.

I can see that the field was received as string (that's good):

inputObject {{  "When": "2016-05-31T14:12:45.753Z" }} Newtonsoft.Json.Linq.JToken {Newtonsoft.Json.Linq.JObject}

However, even though the target field is string the value of inputObject["When"] is a parsed as a timestamp.

    inputObject["When"] {31/05/2016 14:12:45}   Newtonsoft.Json.Linq.JToken {Newtonsoft.Json.Linq.JValue}

Then

            JToken whenValue = inputObject["When"];
            if (whenValue != null && whenValue.Type != JTokenType.Null)
            {
                this.When = ((string)whenValue);
            }

In the end this.When is a string with value 31/05/2016 14:12:45.

Is there an option to prevent json.net from parsing the date and then casting it to string again?

Please remember that this transformation happens in auto generated code so I'm looking for some way of decorating the field on the server side which would make Swagger mark it somehow and then the generated classes would avoid the deserialize/serialize issue.

Something like:

          [JsonProperty("This really is a string, leave it alone")]
          public string When { get; private set; }
tymtam
  • 31,798
  • 8
  • 86
  • 126
  • This may shed some light on your issue... http://weblog.west-wind.com/posts/2014/Jan/06/JavaScript-JSON-Date-Parsing-and-real-Dates .. it is probably easier to reserialise the deserialised date after the fact. – Paul Zahra Jun 02 '16 at 09:02
  • You could also perhaps override the json date deserialiser for this 'json request' see http://stackoverflow.com/questions/11856694/json-net-disable-the-deserialization-on-datetime – Paul Zahra Jun 02 '16 at 09:04
  • 1
    Are you wanting all date values to be handled as string, or just this one? Json.Net does have a global [`DateParseHandling`](http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_DateParseHandling.htm) setting in the [`JsonSerializerSettings`](http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonSerializerSettings.htm) class which you could set to `None` to prevent date strings from being parsed. Unfortunately, there is not a way to set this via a `[JsonProperty]` attribute on a single field. – Brian Rogers Jun 02 '16 at 14:39
  • @BrianRogers Please submit your comment as an answer so that I can mark it as accepted solution :) – tymtam Jun 03 '16 at 00:11
  • 1
    @BrianRogers Actually, this doesn't work as the original json is parsed using jtoken.parse - which doesn't honor JsonSerializerSettings. – tymtam Jun 03 '16 at 00:44
  • @Tymski - Is there any way to make the code use `JsonConvert.DeserializeObject()` instead of `JToken.Parse()`? If so, that would allow you to use the settings while still getting a `JToken`. – Brian Rogers Jun 03 '16 at 14:32

2 Answers2

1

(Answering my own question)

I needed a solution quickly and this is my temporary solution, for the record.

I format the date as

"When": "2016-05-31 14:12:45"

and not

"When": "2016-05-31T14:12:45.753Z"

This prevents it from being interpreted. The front end (javascript) code knows that timestamps from the API are UTC and it appends 'Z' before transforming the timestamp to local time and formatting for display, e.g:

 <td>{{vm.prettyDateTimeFormat(item.StatusDate+'Z')}}</td>

The ctrl code:

  vm.prettyDateTimeFormat = function (dateString)
    {
        var momentDate = moment(dateString, "YYYY-MM-DD HH:mm:ssZZ");
        if (typeof(momentDate) === "undefined" || (!momentDate.isValid()))
        {
            return dateString;
        }

        //The format needs to be sortable as it ends up in the grid.
        var nicePrettyDate = momentDate.format('YYYY-MM-DD HH:mm:ss');
        return nicePrettyDate;
    }

As far as I don't like this solution it carried us through the demo. This issue is obviously in the back log now to be addressed properly.

tymtam
  • 31,798
  • 8
  • 86
  • 126
-2
 [JsonIgnore]
 public string When { get; private set; }
afrose
  • 169
  • 1
  • 9