dotnet / dotnet/aspnetcore

SystemTextJsonValidationMetadataProvider does not work with FromQueryAttribute

Open
#53,702 0 comments 0 reactions 0 assignees View on GitHub
area-mvc
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Describe the bug

Anytime I use `SystemTextJsonValidationMetadataProvider` with a class that contains properties decorated with `FromQueryAttribute`, the response is BadRequest (400) with a body is empty for `errors`.

Adding support for `FromQueryAttribute` and `FromHeaderAttribute` alongside `JsonPropertyNameAttribute` in `SystemTextJsonValidationMetadataProvider` solves the problem.

```diff
///
/// An implementation of and for
/// the System.Text.Json.Serialization attribute classes.
///
internal class SystemTextJsonValidationMetadataProvider : IDisplayMetadataProvider, IValidationMetadataProvider
{
private readonly JsonNamingPolicy _jsonNamingPolicy;

///
/// Creates a new with the default
///
public SystemTextJsonValidationMetadataProvider() : this(JsonNamingPolicy.CamelCase) { }

///
/// Creates a new with an optional
///
/// The to be used to configure the metadata provider.
public SystemTextJsonValidationMetadataProvider(JsonNamingPolicy namingPolicy)
{
ArgumentNullException.ThrowIfNull(namingPolicy);

_jsonNamingPolicy = namingPolicy;
}

///
public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
{
ArgumentNullException.ThrowIfNull(context);

var propertyName = ReadPropertyNameFrom(context.Attributes);

if (!string.IsNullOrEmpty(propertyName))
{
context.DisplayMetadata.DisplayName = () => propertyName;
}
}

///
public void CreateValidationMetadata(ValidationMetadataProviderContext context)
{
var propertyName = ReadPropertyNameFrom(context.Attributes);

if (string.IsNullOrEmpty(propertyName))
{
propertyName = context.Key.Name is string contextKeyName
? _jsonNamingPolicy.ConvertName(contextKeyName)
: null;
}

context.ValidationMetadata.ValidationModelName = propertyName;
}

private static string? ReadPropertyNameFrom(IReadOnlyList attributes)
- => attributes?.OfType().FirstOrDefault()?.Name
+ => attributes?.OfType().FirstOrDefault()?.Name
+ ?? attributes?.OfType().FirstOrDefault()?.Name
+ ?? attributes?.OfType().FirstOrDefault()?.Name;
}
```

### Expected Behavior

It should pass validation when there are query attributes.

### Steps To Reproduce

_No response_

### Exceptions (if any)

_No response_

### .NET Version

8.0.1

### Anything else?

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.