Repository navigation
Expo Errors and Metadata
Expo returns ErrorDetail values for failed rules. Each contains a human-readable Detail and a JSON Pointer in Pointer. Generated metadata describes the model's rules without running validation.
var registration = new CourseRegistration
{
StudentEmail = "invalid",
CourseCode = "B"
};
if (!registration.TryValidate(out var errors))
{
foreach (var error in errors)
{
Console.WriteLine($"{error.Pointer}: {error.Detail}");
}
}CourseRegistration is defined in Validation models. Expo aggregates failures instead of stopping at the first invalid property. Several rules may report the same pointer, so preserve a collection of messages when grouping errors by field.
| Pointer | Invalid value |
|---|---|
/StudentEmail |
A scalar property |
/CourseIds/2 |
The third collection item |
/Lead/Email |
A nested child's property |
/Guests/0/Email |
A property on the first child in a collection |
Pointers use declared C# property names. A JSON naming policy or [JsonPropertyName] can give the serialized property a different name; validation pointers still use the C# name. JSON Pointer escaping replaces ~ with ~0 and / with ~1 in path segments.
Most built-in rules take an optional message as their last argument:
[StringHasMinimumLength(2, "A course code needs at least two characters.")]
public string? CourseCode { get; init; }Generated comparison and regex attributes also accept an optional message. Reusable custom attributes can expose a message, while model-specific custom methods return their failure strings directly.
Expo supplies a default message when none is specified. Choose a custom message when your users need a domain term or a useful correction.
Each Expo model exposes static ExpoModelMetadata Metadata:
foreach (var property in CourseRegistration.Metadata.Properties)
{
Console.WriteLine($"{property.Name}: {property.Pointer}");
foreach (var rule in property.Rules)
{
Console.WriteLine($"{rule.Kind}: {rule.Message}");
}
}Each property entry contains its name, escaped pointer, ordered rules, and IsNestedValidatable flag. Rule entries can include a constant value, compared property name, message, custom rule name, regex pattern, or format, depending on the rule kind.
Metadata describes constraints rather than a validation outcome. A custom rule's metadata identifies the rule; call TryValidate to evaluate its code against an actual model. Nested models expose their own metadata.
For HTTP failure responses, see Expo validation in ASP.NET Core. For publishing constraints in API schemas, see Expo OpenAPI.
- Home
- Getting started
-
Package guides
- Partie
- Expo
-
Mise
- Database setup
- Table mappings
- Aliases
- Relationships
- Result rows
- SQL interpolation
- Queries
- Filtering
- Joins
- Aggregation
- Paging and ordering
- Subqueries
- Set operations
- Common table expressions
- Readers
- Streaming
- Writers
- Inserts
- Updates
- Deletes
- Returned rows
- Custom SQL and procedures
- Transactions
- Resource lifetimes
- Database dialects
- Diagnostics
- Integrations
- Recipes
- Reference
- Troubleshooting
- Development