diff --git a/src/NJsonSchema.CodeGeneration.CSharp.Tests/ValidationAttributesTests.cs b/src/NJsonSchema.CodeGeneration.CSharp.Tests/ValidationAttributesTests.cs index 5c97d646c..3a026aebf 100644 --- a/src/NJsonSchema.CodeGeneration.CSharp.Tests/ValidationAttributesTests.cs +++ b/src/NJsonSchema.CodeGeneration.CSharp.Tests/ValidationAttributesTests.cs @@ -189,7 +189,7 @@ public async Task When_int64_property_has_minimum_then_range_attribute_is_render Assert.Null(schema.Properties["value"].Minimum); Assert.Equal(10, schema.Properties["value"].ActualSchema.Minimum); - Assert.Contains("[System.ComponentModel.DataAnnotations.Range(10D, double.MaxValue)]\n" + + Assert.Contains("[System.ComponentModel.DataAnnotations.Range(10L, long.MaxValue)]\n" + " public long Value { get; set; }\n", code); } @@ -229,7 +229,7 @@ public async Task When_integer_property_has_minimum_and_maximum_that_are_int64_t Assert.Equal(10000000000m, schema.Properties["value"].ActualSchema.Maximum); // expect the integer to be converted to an int64 - Assert.Contains("[System.ComponentModel.DataAnnotations.Range(-10000000000D, 10000000000D)]\n" + + Assert.Contains("[System.ComponentModel.DataAnnotations.Range(-10000000000L, 10000000000L)]\n" + " public long Value { get; set; }\n", code); } diff --git a/src/NJsonSchema.CodeGeneration.CSharp.Tests/ValueGeneratorTests.cs b/src/NJsonSchema.CodeGeneration.CSharp.Tests/ValueGeneratorTests.cs index e81fd6342..2322d9e0a 100644 --- a/src/NJsonSchema.CodeGeneration.CSharp.Tests/ValueGeneratorTests.cs +++ b/src/NJsonSchema.CodeGeneration.CSharp.Tests/ValueGeneratorTests.cs @@ -33,6 +33,43 @@ public async Task When_schema_contains_range_then_code_is_correctly_generated() Assert.Contains("[System.ComponentModel.DataAnnotations.Range(2, int.MaxValue)]", code); } + [Theory] + [InlineData("integer", JsonFormatStrings.Integer, "1, int.MaxValue")] + [InlineData("integer", JsonFormatStrings.Long, "1L, long.MaxValue")] + [InlineData("integer", JsonFormatStrings.ULong, "1UL, ulong.MaxValue")] + [InlineData("number", JsonFormatStrings.Float, "1F, float.MaxValue")] + [InlineData("number", JsonFormatStrings.Double, "1D, double.MaxValue")] + [InlineData("number", JsonFormatStrings.Decimal, "1M, decimal.MaxValue")] + public async Task When_schema_contains_range_and_format_then_code_is_correctly_generated(string propertyType, + string propertyFormat, string expectedRange) + { + /// Arrange + var json = $$""" + { + "type": "object", + "properties": { + "pageSize": { + "type": "{{propertyType}}", + "format": "{{propertyFormat}}", + "minimum": 1 + }, + } + } + """; + var schema = await JsonSchema.FromJsonAsync(json); + + //// Act + var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings + { + ClassStyle = CSharpClassStyle.Poco, + SchemaType = SchemaType.Swagger2 + }); + var code = generator.GenerateFile("MyClass"); + + //// Assert + Assert.Contains($"[System.ComponentModel.DataAnnotations.Range({expectedRange})]", code); + } + [Fact] public async Task When_property_is_integer_and_no_format_is_available_then_default_value_is_int32() { diff --git a/src/NJsonSchema.CodeGeneration.CSharp/CSharpValueGenerator.cs b/src/NJsonSchema.CodeGeneration.CSharp/CSharpValueGenerator.cs index 07356edf9..4eaafabca 100644 --- a/src/NJsonSchema.CodeGeneration.CSharp/CSharpValueGenerator.cs +++ b/src/NJsonSchema.CodeGeneration.CSharp/CSharpValueGenerator.cs @@ -98,6 +98,8 @@ public override string GetNumericValue(JsonObjectType type, object value, string return Convert.ToInt32(value, CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture); case JsonFormatStrings.Long: return Convert.ToInt64(value, CultureInfo.InvariantCulture) + "L"; + case JsonFormatStrings.ULong: + return Convert.ToUInt64(value, CultureInfo.InvariantCulture) + "UL"; case JsonFormatStrings.Double: return ConvertNumberToString(value) + "D"; case JsonFormatStrings.Float: diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Models/PropertyModel.cs b/src/NJsonSchema.CodeGeneration.CSharp/Models/PropertyModel.cs index bc1684a9b..903ee59e6 100644 --- a/src/NJsonSchema.CodeGeneration.CSharp/Models/PropertyModel.cs +++ b/src/NJsonSchema.CodeGeneration.CSharp/Models/PropertyModel.cs @@ -8,6 +8,7 @@ using NJsonSchema.Annotations; using System.Globalization; +using System.Linq; using NJsonSchema.CodeGeneration.Models; namespace NJsonSchema.CodeGeneration.CSharp.Models @@ -18,6 +19,16 @@ public class PropertyModel : PropertyModelBase private readonly JsonSchemaProperty _property; private readonly CSharpGeneratorSettings _settings; private readonly CSharpTypeResolver _resolver; + private static readonly string[] RangeFormats = + [ + JsonFormatStrings.Integer, + JsonFormatStrings.Float, + JsonFormatStrings.Double, + JsonFormatStrings.Long, + JsonFormatStrings.ULong, + JsonFormatStrings.Decimal + ]; + /// Initializes a new instance of the class. /// The class template model. @@ -139,8 +150,8 @@ public string RangeMinimumValue { var schema = _property.ActualSchema; var propertyFormat = GetSchemaFormat(schema); - var format = propertyFormat == JsonFormatStrings.Integer ? JsonFormatStrings.Integer : JsonFormatStrings.Double; - var type = propertyFormat == JsonFormatStrings.Integer ? "int" : "double"; + var format = GetRangeFormat(propertyFormat); + var type = GetRangeType(propertyFormat); var minimum = schema.Minimum; if (minimum.HasValue && schema.IsExclusiveMinimum) @@ -171,8 +182,8 @@ public string RangeMaximumValue { var schema = _property.ActualSchema; var propertyFormat = GetSchemaFormat(schema); - var format = propertyFormat == JsonFormatStrings.Integer ? JsonFormatStrings.Integer : JsonFormatStrings.Double; - var type = propertyFormat == JsonFormatStrings.Integer ? "int" : "double"; + var format = GetRangeFormat(propertyFormat); + var type = GetRangeType(propertyFormat); var maximum = schema.Maximum; if (maximum.HasValue && schema.IsExclusiveMaximum) @@ -311,5 +322,20 @@ public bool RenderRegularExpressionAttribute return schema.Format; } + + private static string GetRangeFormat(string? propertyFormat) => + RangeFormats.Contains(propertyFormat) ? propertyFormat! : JsonFormatStrings.Double; + + private static string GetRangeType(string? propertyFormat) => + propertyFormat switch + { + JsonFormatStrings.Integer => "int", + JsonFormatStrings.Float => "float", + JsonFormatStrings.Double => "double", + JsonFormatStrings.Long => "long", + JsonFormatStrings.ULong => "ulong", + JsonFormatStrings.Decimal => "decimal", + _ => "double", + }; } } \ No newline at end of file