Skip to content

Commit ea938cd

Browse files
committed
fix(validation): push schema location explicitly to set proper location on primitive json types
1 parent acf9527 commit ea938cd

5 files changed

Lines changed: 26 additions & 17 deletions

File tree

src/OpenAPI.WebApiGenerator/CodeGeneration/ParameterGenerator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ internal sealed class ParameterGenerator(
1919
internal string PropertyName { get; } = parameter.GetName().ToPascalCase();
2020
internal bool IsParameterRequired { get; } = parameter.Required;
2121
internal string Location { get; } = parameter.GetLocation();
22+
internal string SchemaLocation { get; } = typeDeclaration.RelativeSchemaLocation;
2223

2324
internal string GenerateRequestProperty() =>
2425
$$"""

src/OpenAPI.WebApiGenerator/CodeGeneration/RequestBodyContentGenerator.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ internal sealed class RequestBodyContentGenerator(
1717
internal string PropertyName { get; } = contentType.ToPascalCase();
1818

1919
internal string ContentType => contentType;
20-
20+
21+
internal string SchemaLocation => typeDeclaration.RelativeSchemaLocation;
2122
internal string GenerateRequestBindingDirective() =>
2223
$"""
2324
{PropertyName} =

src/OpenAPI.WebApiGenerator/CodeGeneration/RequestBodyGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ internal ValidationContext Validate(ValidationContext validationContext, Validat
100100
{{{_contentGenerators.AggregateToString(content =>
101101
$"""
102102
case true when {content.PropertyName} is not null:
103-
return {content.PropertyName}!.Value.Validate(validationContext, validationLevel);
103+
return {content.PropertyName}!.Value.Validate("{content.SchemaLocation}", true, validationContext, validationLevel);
104104
""")}}
105105
default:
106106
{{(_body.Required ?

src/OpenAPI.WebApiGenerator/CodeGeneration/RequestGenerator.cs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,24 +61,14 @@ internal partial class Request
6161
6262
internal ValidationContext Validate(ValidationLevel validationLevel)
6363
{
64-
var validationContext = ValidationContext.ValidContext;{{
64+
var validationContext = ValidationContext.ValidContext.UsingStack().UsingResults();{{
6565
bodyGenerator.GenerateValidateDirective("Body", "validationContext", "validationLevel").Indent(8)
6666
}}{{_parameterGeneratorsGroupedByLocation.AggregateToString(group =>
6767
group.AggregateToString(generator =>
68-
$"validationContext = Validate({group.Key}.{generator.AsRequired(generator.PropertyName)}, {generator.IsParameterRequired.ToString().ToLowerInvariant()});").Trim()).Indent(8)}}
68+
$"""
69+
validationContext = ({group.Key}.{generator.AsRequired(generator.PropertyName)}).Validate("{generator.SchemaLocation}", {generator.IsParameterRequired.ToString().ToLowerInvariant()}, validationContext, validationLevel);
70+
""").Trim()).Indent(8)}}
6971
return validationContext;
70-
71-
ValidationContext Validate<T>(T value,
72-
bool isRequired)
73-
where T : struct, IJsonValue<T>
74-
{
75-
if (!isRequired && value.IsUndefined())
76-
{
77-
return validationContext;
78-
}
79-
80-
return value.Validate(validationContext, validationLevel);
81-
}
8272
}{{_parameterGeneratorsGroupedByLocation.AggregateToString(group =>
8373
$$"""
8474
internal sealed class {{group.Key}}Parameters

src/OpenAPI.WebApiGenerator/CodeGeneration/ValidationExtensionsGenerator.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
internal sealed class ValidationExtensionsGenerator(string @namespace)
44
{
5-
private const string ClassName = "ValidationResultsExtensions";
5+
private const string ClassName = "ValidationExtensions";
66
internal SourceCode GenerateClass() => new($"{ClassName}.g.cs",
77
$$"""
88
#nullable enable
@@ -35,6 +35,23 @@ private static (JsonReference ValidationLocation, JsonReference SchemaLocation,
3535
var schemaLocation = new JsonReference(uri.AsSpan(), location.Value.SchemaLocation.Fragment);
3636
return (location.Value.ValidationLocation, schemaLocation, location.Value.DocumentLocation);
3737
}
38+
39+
internal static ValidationContext Validate<T>(this T value,
40+
string schemaLocation,
41+
bool isRequired,
42+
ValidationContext validationContext,
43+
ValidationLevel validationLevel)
44+
where T : struct, IJsonValue<T>
45+
{
46+
if (!isRequired && value.IsUndefined())
47+
{
48+
return validationContext;
49+
}
50+
51+
var context = validationContext.PushSchemaLocation(schemaLocation);
52+
context = value.Validate(context, validationLevel);
53+
return context.PopLocation();
54+
}
3855
}
3956
#nullable restore
4057
""");

0 commit comments

Comments
 (0)