Anyone want to take bets how long it takes Mark to come in and pimp System.Text.Json
?
Who had 10:13 PM EDT in the over-under?
I mean, Jimmy works for Microsoft now.
Hopefully they reigned in his attitude.
He does have a JSON schema validator module if you want to pay him though.
CS0003782348 - ISO dates in character fields are convertd to dates throughout Kinetic, including REST API.
I donât get what the usefulness is of the datetime handling in the Newtonsoft parser. It just transforms one string representation of a datetime into another string representation. And arguably the least useful of all string representations.
My original title was REST API converts ISO dates in character fields to US dates .
They changed that to include the Kinetic UI, but left out the âUSâ. As if US date strings are âdatesâ and everything else needs to be labelled.
Not quite. It actually makes it into a datetime. And since string was requested, it gets a ToString() called on it.
Which is arguably even worse, because by default, it not only made an unrequested assumption, it did not even offer you an opportunity to change the format lol.
Would this work the other way round? Disable the datetime handling in the parser, pass both dates and strings as strings, and have the strings converted to dates automagically when a date is requested?
From what I understood, itâs only a datetime internally, when it comes out as string, itâs gonna be mangled.
If you disabled the DateTime handling, it should behave as we would expect.
Does it always come out as a string? If so, then my claim that this is just a transformation from one string format to another is true.
If you convert @josecgomez 's example to this, it behaves as expected:
namespace jsonthing;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
class Program
{
static void Main(string[] args)
{
JToken jtokenValue = JsonConvert.DeserializeObject<JToken>(@"{
""ds"": {
""UD40"": [
{
""Company"": ""C001"",
""Key1"": ""2023-07-17T15:43:42.461Z"",
}
]
}
}", new JsonSerializerSettings(){ DateParseHandling = DateParseHandling.None });
var serialized = new JsonSerializer();
JTokenReader jsonReader = new JTokenReader(jtokenValue);
//Loop through token reader
while (jsonReader.Read())
{
if (jsonReader.TokenType == JsonToken.PropertyName)
{
if (jsonReader.Value.ToString() == "Key1")
{
jsonReader.Read();
Console.WriteLine(jsonReader.Value);
}
}
}
}
}
Output: 2023-07-17T15:43:42.461Z
You canât just add:
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
DateParseHandling = DateParseHandling.None
};
and expect it to behave, because the Parse methods donât follow it, if you switch to DeserializeObject, you can however, add that, or specify it on the method like shown.
I didnât take it apart, but I suspect if we look a method or two before the
private static void CreateRow(JsonReader reader, ....)
in Epicors server code, we could see how to fix it.
Newtonsoft does the same thing with Microsoft Dates as well
namespace jsonthing;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
class Program
{
static void Main(string[] args)
{
string jsonPart1 = @"{
""ds"": {
""UD40"": [
{
""Company"": ""C001"",
""Key1"": """;
string jsonPart3 = @""",
}
]
}
}";
JToken jtokenValue1 = JToken.Parse($"{jsonPart1}2023-07-17T15:43:42.461Z{jsonPart3}");
JToken jtokenValue2 = JsonConvert.DeserializeObject<JToken>($"{jsonPart1}2023-07-17T15:43:42.461Z{jsonPart3}", new JsonSerializerSettings(){ DateParseHandling = DateParseHandling.None });
JToken jtokenValue3 = JToken.Parse($"{jsonPart1}/Date(1198908717056)/{jsonPart3}");
JToken jtokenValue4 = JsonConvert.DeserializeObject<JToken>($"{jsonPart1}/Date(1198908717056)/{jsonPart3}", new JsonSerializerSettings(){ DateParseHandling = DateParseHandling.None });
List<JToken> listJToken = new List<JToken>();
listJToken.Add(jtokenValue1);
listJToken.Add(jtokenValue2);
listJToken.Add(jtokenValue3);
listJToken.Add(jtokenValue4);
foreach(JToken jtokenValue in listJToken)
{
var serialized = new JsonSerializer();
JTokenReader jsonReader = new JTokenReader(jtokenValue);
//Loop through token reader
while (jsonReader.Read())
{
if (jsonReader.TokenType == JsonToken.PropertyName)
{
if (jsonReader.Value.ToString() == "Key1")
{
jsonReader.Read();
Console.WriteLine(jsonReader.Value);
}
}
}
}
}
}
Output:
7/17/2023 3:43:42 PM
2023-07-17T15:43:42.461Z
12/29/2007 6:11:57 AM
/Date(1198908717056)/
Well, if it is still one line to change, then JamesNK is not a liar.
Right but then if you sent an actual date it wouldnât work
I donât think we said he was, we said he was an .
Thatâs the responsibility of the the class providing the type no? Maybe Iâm not understanding what you are saying.
I think I understand. No, not the way they have it coded, but they are already building the row column by column. A simple check on the column type for datetime, and a DateTime.Parse will take care of it.
If you pass in Date01 and have that DateHandling set to none you wonât be able to assign the result to the typed Date01 unless you specifically handle each date yourself so you wouldnât be able to easily say just deserialize into this type
Youâd have to go and manually parse ir handle each date field or give it a custom date handler that would somehow know the difference between a string string and a string date lol
Thatâs what Iâm saying they need to do.
I donât think thatâs a big deal, since they are already building the row, column by column.
If newtonsoft had added where it would do the conversion, but keep the original string value, you could leave their stupid defaults, and get the original string. Then epicor could just do a simple check on column type and shove the correct value in based on type, bypassing the parse step. (Of course the parse in that case was done, just in Newtonsoft land)