Search code examples
c#.netjsonjson.net

JToken: Get raw/original JSON value


Is there a way to get the raw/original JSON value from a JToken?

The problem:

var data = JObject.Parse(@"{
    ""SimpleDate"":""2012-05-18T00:00:00Z"",
    ""PatternDate"":""2012-11-07T00:00:00Z""
}");

var value = data["SimpleDate"].Value<string>();

The value is now 05/18/2012 00:00:00 but I need the original string 2012-05-18T00:00:00Z.

Is there a way to get this original value? Also, I cannot change the way how the JObject is created (e.g. change settings), because it is passed as parameter into my class...

(Reference: The original NJsonSchema issue)


Solution

  • You cannot get the original string, date strings are recognized and converted to DateTime structs inside the JsonReader itself. You can see this if you do:

    Console.WriteLine(((JValue)data["SimpleDate"]).Value.GetType()); // Prints System.DateTime
    

    You can, however, extract the dates in ISO 8601 format by doing:

    var value = JsonConvert.SerializeObject(data["SimpleDate"]);
    // value is "2012-05-18T00:00:00Z"
    

    This will always output a JValue in a JSON-appropriate string format. Since your original dates are in this format, this may meet your needs.

    (Honestly, I'm surprised JValue.ToString() outputs dates in non-ISO format, given that JObject.ToString() does output contained dates in ISO format.)

    If you were able to change you settings while reading your JObject, you could use JsonSerializerSettings.DateParseHandling = DateParseHandling.None to disable DateTime recognition:

    var settings = new JsonSerializerSettings { DateParseHandling = DateParseHandling.None };
    var data = JsonConvert.DeserializeObject<JObject>(@"{
        ""SimpleDate"":""2012-05-18T00:00:00Z"",
        ""PatternDate"":""2012-11-07T00:00:00Z""
    }", settings);
    
    var value = data["SimpleDate"].Value<string>();
    
    Debug.WriteLine(value); // Outputs 2012-05-18T00:00:00Z
    

    There's no overload to JObject.Parse() that takes a JsonSerializerSettings, so use DeserializeObject. This setting eventually gets propagated to JsonReader.DateParseHandling.

    Related Newtonsoft docs: