DataAnnotatedModelValidations 4.0.2
See the version list below for details.
dotnet add package DataAnnotatedModelValidations --version 4.0.2
NuGet\Install-Package DataAnnotatedModelValidations -Version 4.0.2
<PackageReference Include="DataAnnotatedModelValidations" Version="4.0.2" />
<PackageVersion Include="DataAnnotatedModelValidations" Version="4.0.2" />
<PackageReference Include="DataAnnotatedModelValidations" />
paket add DataAnnotatedModelValidations --version 4.0.2
#r "nuget: DataAnnotatedModelValidations, 4.0.2"
#:package DataAnnotatedModelValidations@4.0.2
#addin nuget:?package=DataAnnotatedModelValidations&version=4.0.2
#tool nuget:?package=DataAnnotatedModelValidations&version=4.0.2
DataAnnotatedModelValidations
Data Annotated Model Validation Middleware for HotChocolate.
The purpose of this Middleware is to provide the same behavior like a ASP.Net controllers where all models would be validated according to the specified Data Annotations or the IValidatableObject implementation; in essence it's always on.
In addition individual method arguments can be validated using annotations from System.ComponentModel.Annotations.
Usage
Locate your GraphQL Server registration and append .AddDataAnnotationsValidator()
ex.
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// ...
services
.AddGraphQLServer()
.AddDataAnnotationsValidator()
.AddQueryType<Query>();
// ...
}
Excluding a model from being validated
To exclude a certain method argument from being validated just add the IgnoreModelValidation attribute.
ex.
public class Sample
{
[Required]
[MinLength(3)]
[EmailAddress]
public string? Email { get; set; }
}
public class Query
{
public string? GetTextIgnoreValidation([IgnoreModelValidation][MinLength(5)] string? text) => text;
public Sample? GetSampleIgnoreValidation([IgnoreModelValidation] Sample? sample) => sample;
}
Models
In C# one may define models in a multitude of ways.
To help alleviate potential issues consider the following:
Standard Classes
public class Sample
{
[Required]
[MinLength(3)]
[EmailAddress]
public string? Email { get; set; }
}
Records with declared properties
public record Sample
{
[Required]
[MinLength(3)]
[EmailAddress]
public string? Email { get; set; }
}
Records with auto synthesized properties
The auto-property is initialized to the value of the corresponding primary constructor parameter. Attributes can be applied to the synthesized auto-property and its backing field by using
property:orfield:targets for attributes syntactically applied to the corresponding record parameter.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-9.0/records
So per the documentation and following the guideline, a solution to the challenge mentioned would be adding the property: prefix to the validation attribute.
public record Sample(
[property:Required]
[property:MinLength(3)]
[property:EmailAddress]
string? Email
);
Notes
When implementing the IValidatableObject interface HotChocolate considers the Validate as a resolver; to avoid getting schema errors said method needs to be ignored.
ex.
public class Sample : IValidatableObject
{
[Required]
[MinLength(3)]
[EmailAddress]
public string? Email { get; set; }
[GraphQLIgnore]
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) =>
Email?.StartsWith("no-property-name") == true
? new[] { new ValidationResult("no-property-name") }
: Enumerable.Empty<ValidationResult>();
}
Numerical sequences
If you need to support numerical sequences in your validation results, consider adding the names as FieldName:[index].
The field name will be transformed in the error path as fieldName,_index_.
{
"errors": [
{
"message": "The field Count must be between 1 and 10.",
"path": ["sample", "obj", "children", "_2_", "count"],
"extensions": {
"code": "DAMV-400",
"field": "sample",
"type": "Mutation",
"specifiedBy": "http://spec.graphql.org/June2018/#sec-Values-of-Correct-Type"
}
}
]
}
If you choose to omit the : character and add the names as FieldName[index] the field name and the index will be represented as one entry, fieldName_index_.
{
"errors": [
{
"message": "The field Count must be between 1 and 10.",
"path": ["sample", "obj", "children_2_", "count"],
"extensions": {
"code": "DAMV-400",
"field": "sample",
"type": "Mutation",
"specifiedBy": "http://spec.graphql.org/June2018/#sec-Values-of-Correct-Type"
}
}
]
}
Multiple members
If multiple member names are added they will be treated as distinct error messages.
Ex. validation error '"Some validation error!"' was assigned to properties hello and world:
{
"errors": [
{
"message": "Some validation error!",
"path": ["sample", "obj", "hello"],
"extensions": {
"code": "DAMV-400",
"field": "sample",
"type": "Query",
"specifiedBy": "http://spec.graphql.org/June2018/#sec-Values-of-Correct-Type"
}
},
{
"message": "Some validation error!",
"path": ["sample", "obj", "world"],
"extensions": {
"code": "DAMV-400",
"field": "sample",
"type": "Query",
"specifiedBy": "http://spec.graphql.org/June2018/#sec-Values-of-Correct-Type"
}
}
],
"data": {
"sample": null
}
}
Property nesting
If there is a need to express a nested relationship of a property and it's parent, consider adding the names separated by a colon as ParentName:FieldName:[index]
Similar Projects
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net6.0
- HotChocolate.Execution (>= 13.0.5)
- Humanizer (>= 2.14.1)
-
net7.0
- HotChocolate.Execution (>= 13.0.5)
- Humanizer (>= 2.14.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 9.0.0 | 5,030 | 11/20/2025 |
| 8.1.2 | 32,932 | 4/27/2025 |
| 8.1.1 | 7,975 | 2/19/2025 |
| 8.1.0 | 848 | 2/17/2025 |
| 8.0.1 | 848 | 2/16/2025 |
| 8.0.0 | 769 | 2/15/2025 |
| 7.0.0 | 3,663 | 2/7/2025 |
| 6.3.0 | 25,475 | 12/25/2024 |
| 6.2.0 | 8,632 | 12/4/2024 |
| 6.1.0 | 2,652 | 11/16/2024 |
| 6.0.0 | 11,321 | 10/16/2024 |
| 5.2.0 | 89,707 | 3/15/2024 |
| 5.1.0 | 40,496 | 11/21/2023 |
| 5.0.0 | 1,016 | 11/21/2023 |
| 4.2.0 | 3,542 | 10/26/2023 |
| 4.1.0 | 18,502 | 8/22/2023 |
| 4.0.2 | 64,069 | 5/5/2023 |
| 4.0.1 | 65,008 | 3/10/2023 |
| 4.0.0 | 5,383 | 2/13/2023 |
| 3.0.1 | 8,322 | 1/15/2023 |