The Range attribute declares numeric bounds as model metadata, keeping invalid values out of the application before an action stores or processes the bound object. section 29.5 section 19.5.4
Use the attribute where the model needs a bounded value:
- Apply [Range(1, 1000)] to a decimal Price property to reject values outside the inclusive lower and upper limits. section 19.5.4 section 29.5
- Apply [Range(1, long.MaxValue)] to identifier properties whose default zero value should not be accepted when the client omits them. section 19.5.4
- Supply ErrorMessage when the default response is too vague, such as [Range(1, 999999, ErrorMessage = "Please enter a positive price")]. section 29.5
- Use the attribute with numeric values or property types implementing IComparable; boolean constraints can also use Range with typeof(bool). section 29.5
Rejecting an incomplete product request
A ProductBindingTarget can constrain Price, CategoryId, and SupplierId with Range attributes. The POST action checks ModelState.IsValid before converting the target, saving it, and returning Ok; invalid input returns BadRequest(ModelState). Posting only {"Name":"Boot Laces"} produces range errors because the primitive properties remain zero. section 19.5.4
Listing 29.15 Applying validation attributes in the Product.cs file in the Models folder
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace WebApp.Models {
public class Product {
public long ProductId { get; set; }
[Required(ErrorMessage = "Please enter a name")]
public required string Name { get; set; }
[Range(1, 999999, ErrorMessage = "Please enter a positive price")]
[Column(TypeName = "decimal(8, 2)")]
public decimal Price { get; set; }
public long CategoryId { get; set; }
public Category? Category { get; set; }
public long SupplierId { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public Supplier? Supplier { get; set; }
}
}
Inspect the complete Product model showing a bounded Price property alongside its database column configuration and custom validation message. section 29.5
