From e4483d829e32f0a2be06da006b9d56597d0870cf Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Sat, 7 Mar 2026 15:09:25 +0200 Subject: [PATCH 1/2] Fix MinLength incorrectly added to DateTime and Date types When a DateTime, DateTimeOffset, DateOnly, or TimeOnly property has [Required], it was getting MinLength=1 because these types are represented as strings with a format in JSON Schema. This is incorrect - MinLength should only apply to actual string properties, not date/time types that use string representation. Added IsDateTimeFormat check to exclude date-time, date, time, duration, and time-span formats from the MinLength=1 logic. Fixes #1583 Co-Authored-By: Claude Opus 4.6 --- .../Generation/AttributeGenerationTests.cs | 32 +++++++++++++++++++ .../Generation/JsonSchemaGenerator.cs | 9 +++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/NJsonSchema.Tests/Generation/AttributeGenerationTests.cs b/src/NJsonSchema.Tests/Generation/AttributeGenerationTests.cs index 46067a9af..067c5c6db 100644 --- a/src/NJsonSchema.Tests/Generation/AttributeGenerationTests.cs +++ b/src/NJsonSchema.Tests/Generation/AttributeGenerationTests.cs @@ -299,5 +299,37 @@ public async Task When_dictionary_property_has_regex_attribute_then_regex_is_add Assert.Null(schema.Properties["Versions"].Pattern); Assert.NotNull(schema.Properties["Versions"].AdditionalPropertiesSchema.ActualSchema.Pattern); } + + public class ClassWithRequiredDateTimeProperties + { + [Required] + public DateTime RequiredDateTime { get; set; } + + [Required] + public DateTimeOffset RequiredDateTimeOffset { get; set; } + + [Required] + public DateOnly RequiredDateOnly { get; set; } + + [Required] + public TimeOnly RequiredTimeOnly { get; set; } + + [Required] + public string RequiredString { get; set; } + } + + [Fact] + public void When_required_DateTime_then_MinLength_is_not_set() + { + // Act + var schema = NewtonsoftJsonSchemaGenerator.FromType(); + + // Assert + Assert.Null(schema.Properties["RequiredDateTime"].MinLength); + Assert.Null(schema.Properties["RequiredDateTimeOffset"].MinLength); + Assert.Null(schema.Properties["RequiredDateOnly"].MinLength); + Assert.Null(schema.Properties["RequiredTimeOnly"].MinLength); + Assert.Equal(1, schema.Properties["RequiredString"].MinLength); + } } } \ No newline at end of file diff --git a/src/NJsonSchema/Generation/JsonSchemaGenerator.cs b/src/NJsonSchema/Generation/JsonSchemaGenerator.cs index eadb12a98..7392fa81a 100644 --- a/src/NJsonSchema/Generation/JsonSchemaGenerator.cs +++ b/src/NJsonSchema/Generation/JsonSchemaGenerator.cs @@ -1205,7 +1205,8 @@ public void AddProperty( if (hasRequiredAttribute && !propertyTypeDescription.IsEnum && propertyTypeDescription.Type == JsonObjectType.String && - !requiredAttribute.TryGetPropertyValue("AllowEmptyStrings", false)) + !requiredAttribute.TryGetPropertyValue("AllowEmptyStrings", false) && + !IsDateTimeFormat(propertyTypeDescription.Format)) { propertySchema.MinLength = 1; } @@ -1306,6 +1307,12 @@ public bool IsPropertyIgnoredBySettings(ContextualAccessorInfo accessorInfo) return accessorInfo.GetAttributes(true).FirstAssignableToTypeNameOrDefault("DataMemberAttribute", TypeNameStyle.Name); } + private static bool IsDateTimeFormat(string? format) + { + return format is JsonFormatStrings.DateTime or JsonFormatStrings.Date or JsonFormatStrings.Time + or JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan; + } + private static bool HasDataContractAttribute(Type parentType) { return parentType.ToCachedType() From d86353b8b68f33a89549102fda78cc372b34e500 Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Sat, 7 Mar 2026 15:30:30 +0200 Subject: [PATCH 2/2] Fix net472 build: guard DateOnly/TimeOnly with preprocessor directive DateOnly and TimeOnly are .NET 6+ only types, not available in .NET Framework 4.7.2. Wrap them with #if NET6_0_OR_GREATER. Co-Authored-By: Claude Opus 4.6 --- src/NJsonSchema.Tests/Generation/AttributeGenerationTests.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/NJsonSchema.Tests/Generation/AttributeGenerationTests.cs b/src/NJsonSchema.Tests/Generation/AttributeGenerationTests.cs index 067c5c6db..a3dc11d84 100644 --- a/src/NJsonSchema.Tests/Generation/AttributeGenerationTests.cs +++ b/src/NJsonSchema.Tests/Generation/AttributeGenerationTests.cs @@ -308,11 +308,13 @@ public class ClassWithRequiredDateTimeProperties [Required] public DateTimeOffset RequiredDateTimeOffset { get; set; } +#if NET6_0_OR_GREATER [Required] public DateOnly RequiredDateOnly { get; set; } [Required] public TimeOnly RequiredTimeOnly { get; set; } +#endif [Required] public string RequiredString { get; set; } @@ -327,8 +329,10 @@ public void When_required_DateTime_then_MinLength_is_not_set() // Assert Assert.Null(schema.Properties["RequiredDateTime"].MinLength); Assert.Null(schema.Properties["RequiredDateTimeOffset"].MinLength); +#if NET6_0_OR_GREATER Assert.Null(schema.Properties["RequiredDateOnly"].MinLength); Assert.Null(schema.Properties["RequiredTimeOnly"].MinLength); +#endif Assert.Equal(1, schema.Properties["RequiredString"].MinLength); } }