-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support more date-time formats for JSON deserialization #85545
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsDescriptionOriginally reported to JsonSchema.Net here. The report says that System.Text.Json deserialization only supports ISO 8601 date-time formats. However JSON Schema specifies that RFC 3339 formats are to be used. Thus a problem exists when a payload that has been validated by the schema: {
"type": "string",
"format": "date-time"
} (with This restriction is especially odd since Reproduction StepsPlease see attached solution. [Test]
public void Test1()
{
var serializerOptions = new JsonSerializerOptions
{
WriteIndented = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
var jsonDate = JsonNode.Parse("\"2023-03-20 05:41:23.3881075\"");
Console.WriteLine(jsonDate.AsJsonString());
JsonSchema schema = new JsonSchemaBuilder()
.Type(SchemaValueType.String)
.Format(Formats.DateTime);
var results = schema.Evaluate(jsonDate, new EvaluationOptions
{
OutputFormat = OutputFormat.List,
RequireFormatValidation = true
});
Console.WriteLine(JsonSerializer.Serialize(results, serializerOptions));
Assert.IsTrue(results.IsValid);
var date = jsonDate.Deserialize<DateTime>(); // fails
Console.WriteLine(date);
}
[Test]
public void DateTimeParsing()
{
var date = DateTime.Parse("2023-03-20 05:41:23.3881075"); // works
Console.WriteLine(date);
} Expected behaviorDate/time deserialization is more tolerant and accepts any format that can be handled by Actual behaviorDate/time deserialization MUST be ISO 8601-1:2019. Regression?Unsure. Known WorkaroundsA custom converter should be able to handle this, but it shouldn't really be necessary. ConfigurationThese tests run in .Net 6. JsonSchema.Net is .Net Standard 2.0. Other informationMaybe serialization could be configurable. Date-time format comparison: https://ijmacd.github.io/rfc3339-iso8601/
|
The primitive types supported by the serializer each support only one format for consistent implementation simplicity and to encourage the design of type/data models that would yield better performance during (de)serialization routines. Here are a few similar issues that we've closed following this principle - https://github.com/dotnet/runtime/issues?q=is%3Aissue+label%3Aarea-System.Text.Json+formats+is%3Aclosed. As you note, a custom converter can handle this. |
This issue has been marked |
I completely agree that this needs to be a goal, and serializing to specific formats can help accomplish this. However, we need to be tolerant in what we accept. (Ref: Postel's Law / Robustness Principle). I suggest that the deserializer expect the strict format, and, if that fails, allow other formats. Maybe this can be hidden behind a serialization option, but it should definitely be supported. |
I think that's reasonable provided that we don't compromise the fast path. |
I suggest that any such feature be opt-in to avoid breaking people who expect/depend on the strict ISO representation. Perhaps a public converter like what we have in |
I like that idea, @layomia. Something that can be optionally composed in is a good idea, with the converter's behavior being standalone. |
I think I (and my users) would be satisfied with an option to control this. |
You mention that only ISO 8601-1:2019 formats can be parsed; however I'm sure that you're aware it's actually only a small subset of valid ISO 8601-1:2019 DateTime values which are correctly deserialized;
As a comparison here are the RFC 3339 formats which can currently correctly be deserialized.
To be clear, I'm not suggesting supporting all valid formats is necessarily a priority; but explicitness (along with Postel's Law) is usually an excellent start. |
Thanks, @IJMacD! That's very thorough. From that, it looks like only the following formats are supported by both .Net and JSON Schema.
This is good info to have documented! |
I think I'm happy with having this documented. Thanks! |
Description
Originally reported to JsonSchema.Net here.
The report says that System.Text.Json deserialization only supports ISO 8601 date-time formats. However JSON Schema specifies that RFC 3339 formats are to be used.
Thus a problem exists when a payload that has been validated by the schema:
(with
format
validation enabled) fails to deserialize because there is a mismatch between the format required by JSON Schema and the formats supported by System.Text.Json's deserialization.This restriction is especially odd since
DateTime.Parse()
supports these formats.Reproduction Steps
Please see attached solution.
Expected behavior
Date/time deserialization is more tolerant and accepts any format that can be handled by
DateTime.Parse()
.Actual behavior
Date/time deserialization MUST be ISO 8601-1:2019.
Regression?
Unsure.
Known Workarounds
A custom converter should be able to handle this, but it shouldn't really be necessary.
Configuration
These tests run in .Net 6. JsonSchema.Net is .Net Standard 2.0.
Other information
Maybe serialization could be configurable.
Date-time format comparison: https://ijmacd.github.io/rfc3339-iso8601/
The text was updated successfully, but these errors were encountered: