New DataAnnotations in .NET 8.0

.NET 8 introduces new DataAnnotations to help you validate data easily. You can check if string lengths fall within set limits, ensure numbers are within a certain range, specify which values are allowed or not, and validate Base64 strings. This article explains how to use these new features.

To demonstrate each dataannotations, I have used the below tools.

  1. VS 2022 Community Edition
  2. .Net 8.0
  3. Web API
  4. .http file for testing.

You can download the source from GitHub.

The below class will have the complete list of new data annotations available in .NET 8.0.

using System.ComponentModel.DataAnnotations;

namespace NewDataAnnotationsInDotNet8
{
    public class Item
    {
        [Length(5, 20)]
        public string Name { get; set; }

        [Range(250, 2000, MinimumIsExclusive = true, MaximumIsExclusive = false)]
        public double Price { get; set; }

        [AllowedValues("Phones","Tabs")]
        public string Category { get; set; }

        [DeniedValues("Monitors")]
        public string SubCategory { get; set; }

        [Base64String]
        public string Description { get; set; }
    }
}

The endpoint which will be accepting this as input is below.

using System.ComponentModel.DataAnnotations;

namespace NewDataAnnotationsInDotNet8
{
    public static class PlaceOrderEndPoint
    {
        public static void AddPlaceOrderEndPoint(this IEndpointRouteBuilder app)
        {

            var placeOrderEndPoint = app.MapGroup("api/v1");
            placeOrderEndPoint.PlaceOrdrEndPoint();
        }

        private static void PlaceOrdrEndPoint(this RouteGroupBuilder routeGroup)
        {
            routeGroup.MapPost("/placeorder", async (Item item) =>
            {
                var validationResults = new List<ValidationResult>();
                var validationContext = new ValidationContext(item, null, null);
                bool isValid = Validator.TryValidateObject(item, validationContext, validationResults, true);

                if (!isValid)
                {
                    return Results.BadRequest(validationResults);
                }
                // Place order logic
                return Results.Created("/order/1", item);
            })
            .WithName("PlaceOrder")
            .WithOpenApi();

        }
    }
}

LengthAttribute

The System.ComponentModel.DataAnnotations.LengthAttribute sets the shortest and longest allowed lengths for strings or collections. For example, the Name property must be at least 2 characters long and no more than 20 characters.

MinimumIsExclusive & MaximumIsExclusive in Range

The RangeAttribute.MinimumIsExclusive and RangeAttribute.MaximumIsExclusive specifies whether a number is included in the allowed range.

For the Price property, the Range attribute sets the minimum value to 250 (exclusive), meaning the lowest acceptable value is 251. The maximum value is 2000 (not exclusive), meaning the highest acceptable value is 2000.

AllowedValuesAttribute & DeniedValuesAttribute

The AllowedValuesAttribute and DeniedValuesAttribute specify which values are allowed or denied.

For the Category property, only "Phones" and "Tabs" are allowed, so any other value is invalid.

For the SubCategory property, only "Monitors" are denied, so any other value is valid.

Base64StringAttribute

The Base64StringAttribute checks if a string is a valid Base64 format.

For the Description property, this attribute means the value must be a Base64 string.

Time to execute the code

If you are going to execute the below request in .http file.

POST {{NewDataAnnotationsInDotNet8_HostAddress}}/placeorder/
Content-Type: application/json
Accept-Language: en-US,en; q=0.9

{
  "name": "",
  "price": 101,
  "category": "string",
  "subCategory": "string",
  "description": "string"

}

You will get the response below.

[
  {
    "memberNames": [
      "Name"
    ],
    "errorMessage": "The field Name must be a string or collection type with a minimum length of '5' and maximum length of '20'."
  },
  {
    "memberNames": [
      "Price"
    ],
    "errorMessage": "The field Price must be between 250 exclusive and 2000."
  },
  {
    "memberNames": [
      "Category"
    ],
    "errorMessage": "The Category field does not equal any of the values specified in AllowedValuesAttribute."
  },
  {
    "memberNames": [
      "Description"
    ],
    "errorMessage": "The Description field is not a valid Base64 encoding."
  }
]

Conclusion

The newest DataAnnotations in .NET offer helpful validation features. They let developers easily set rules like minimum and maximum lengths for strings, minimum and maximum values for numbers, and specify allowed or denied values. They also validate Base64 strings. These improvements give developers a handy set of tools to ensure data meets specific requirements in their applications.