Socolin / DataAnnotatedModelValidations

Data Annotated Model Middleware for HotChocolate

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

DataAnnotatedModelValidations

NuGet Version NuGet Downloads License: MIT

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.

Nuget

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;
}

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

About

Data Annotated Model Middleware for HotChocolate

License:MIT License


Languages

Language:C# 100.0%