DataAnnotatedModelValidations 8.1.2
dotnet add package DataAnnotatedModelValidations --version 8.1.2
NuGet\Install-Package DataAnnotatedModelValidations -Version 8.1.2
<PackageReference Include="DataAnnotatedModelValidations" Version="8.1.2" />
<PackageVersion Include="DataAnnotatedModelValidations" Version="8.1.2" />
<PackageReference Include="DataAnnotatedModelValidations" />
paket add DataAnnotatedModelValidations --version 8.1.2
#r "nuget: DataAnnotatedModelValidations, 8.1.2"
#:package DataAnnotatedModelValidations@8.1.2
#addin nuget:?package=DataAnnotatedModelValidations&version=8.1.2
#tool nuget:?package=DataAnnotatedModelValidations&version=8.1.2
DataAnnotatedModelValidations
Data Annotated Model Validation Middleware for HotChocolate.
The purpose of this Middleware is to provide the same behavior as 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
.
Compatibility
Current Releases
HotChocolate Version | DataAnnotatedModelValidations Version | .NET Version |
---|---|---|
15.0.3 or higher | 8.1.2 | .NET 8, 9 |
15.0.3 or higher | 8.1.1 | .NET 8, 9 |
15.0.3 or higher | 8.1.0 | .NET 8, 9 |
15.0.3 or higher | 8.0.1 | .NET 8, 9 |
15.0.3 or higher | 8.0.0 | .NET 8, 9 |
15.0.3 or higher | 7.0.0 | .NET 8, 9 |
14.3.0 or higher | 6.3.0 | .NET 8, 9 |
14.2.0 or higher | 6.2.0 | .NET 8, 9 |
14.1.0 or higher | 6.1.0 | .NET 8, 9 |
14.0.0 or higher | 6.0.0 | .NET 8 |
Past Releases
HotChocolate Version | Last DataAnnotatedModelValidations Version | .NET Version |
---|---|---|
13.9.0 or higher | 5.2.0 | .NET 6, 7, 8 |
13.7.0 or higher | 4.2.0 | .NET 6, 7 |
12.16.0 or higher | 3.0.1 | .NET 7 |
12.4.1 or higher | 2.1.4 | .NET 6 |
📝For more information please visit https://www.nuget.org/packages/DataAnnotatedModelValidations/#versions-body-tab
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 or Records with declared properties
public class Sample
{
[Required]
[MinLength(3)]
[EmailAddress]
public string? Email { get; set; }
}
public record SampleRecord
{
[Required]
[MinLength(3)]
[EmailAddress]
public string? Email { get; set; }
}
Standard Classes or Records with declared properties using top level attributes
[MyCustomObjectValidator]
public class Sample
{
[Required]
[MinLength(3)]
[EmailAddress]
public string? Email { get; set; }
}
[MyCustomObjectValidator]
public record SampleRecord
{
[Required]
[MinLength(3)]
[EmailAddress]
public string? Email { get; set; }
}
Standard Classes or Records with inline parameter level attributes
public class Sample
{
[Required]
[MinLength(3)]
[EmailAddress]
public string? Email { get; set; }
}
public class Query
{
public Sample? GetSampleWithParameterLevelAttribute([MyCustomObjectValidator] Sample? sample) => sample;
}
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": "https://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": "https://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": "https://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": "https://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 | net8.0 is compatible. 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 is compatible. 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. |
-
net8.0
- HotChocolate.Execution (>= 15.0.3)
- Humanizer (>= 2.14.1)
-
net9.0
- HotChocolate.Execution (>= 15.0.3)
- 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 |
---|---|---|
8.1.2 | 7,950 | 4/27/2025 |
8.1.1 | 6,676 | 2/19/2025 |
8.1.0 | 412 | 2/17/2025 |
8.0.1 | 416 | 2/16/2025 |
8.0.0 | 342 | 2/15/2025 |
7.0.0 | 2,033 | 2/7/2025 |
6.3.0 | 14,390 | 12/25/2024 |
6.2.0 | 5,339 | 12/4/2024 |
6.1.0 | 2,216 | 11/16/2024 |
6.0.0 | 7,424 | 10/16/2024 |
5.2.0 | 70,874 | 3/15/2024 |
5.1.0 | 36,370 | 11/21/2023 |
5.0.0 | 587 | 11/21/2023 |
4.2.0 | 3,047 | 10/26/2023 |
4.1.0 | 17,822 | 8/22/2023 |
4.0.2 | 58,958 | 5/5/2023 |
4.0.1 | 49,183 | 3/10/2023 |
4.0.0 | 4,846 | 2/13/2023 |
3.0.1 | 7,859 | 1/15/2023 |
3.0.0 | 366 | 1/15/2023 |
2.1.4 | 356,288 | 10/22/2022 |
2.1.3 | 554 | 10/20/2022 |
2.1.2 | 456 | 10/20/2022 |
2.1.1 | 586 | 10/19/2022 |
2.1.0 | 98,978 | 1/11/2022 |
2.0.1 | 4,488 | 10/10/2021 |
2.0.0 | 401 | 10/1/2021 |
1.5.3 | 16,932 | 8/30/2021 |
1.5.2 | 431 | 8/11/2021 |
1.5.1 | 584 | 7/6/2021 |
1.5.0 | 696 | 6/10/2021 |
1.4.0 | 593 | 4/21/2021 |
1.3.0 | 458 | 4/17/2021 |
1.2.1 | 434 | 4/15/2021 |
1.2.0 | 424 | 4/13/2021 |
1.1.0 | 537 | 3/30/2021 |
1.0.0 | 711 | 3/11/2021 |