Skip to content

Getting Started Expo

SteffenBlake edited this page Sep 28, 2026 · 3 revisions

Validation with Expo

Expo checks request data against rules on your model and reports which fields fail. Use [Expo] on a request model to generate its validation method.

It is highly recommended that you set up Partie first if you want automatic request binding and validation in the request pipeline.

Validate request models

Install these packages in the project that contains the models you want to validate:

dotnet add package Brigade.Net.Expo
dotnet add package Brigade.Net.Expo.Engines.Domain

Brigade.Net.Expo provides the core classes for defining validation on models.

Brigade.Net.Expo.Engines.Domain source generates validation for models marked with [Expo].

Integrating with ASP.NET Core

For ASP.NET Core APIs, install the Partie integration packages in the project that defines your routes:

dotnet add package Brigade.Net.Partie.Extensions.Expo
dotnet add package Brigade.Net.Partie.Extensions.Expo.Engines.AspNetCore

Brigade.Net.Partie.Extensions.Expo adds automatic Expo validation to Partie routes. Invalid requests receive a Bad Request response before reaching your handlers.

Brigade.Net.Partie.Extensions.Expo.Engines.AspNetCore generates a helper that adds Expo’s validation rules to ASP.NET Core’s OpenAPI documents.

Add automatic validation to the Partie system

Add [ExpoValidationPartie] to a route group to reject invalid requests on its routes, automatically short circuiting them out into ProblemDetails schema responses with error code 400.

[BrigadeGroup("/api/v1")]
...
[ExpoValidationPartie]
public static partial class RoutingV1
{
    ...
}

With both Parties registered, Expo validates each incoming request. Invalid requests receive HTTP 400 with a ProblemDetails-shaped body containing field errors; the handler does not run.

Enable Expo OpenAPI metadata in ASP.NET Core

Add AddExpo() to include Expo constraints in generated OpenAPI schemas:

// Program.cs

// Add Expo validation metadata to generated OpenAPI schemas.
builder.Services.AddOpenApi(options => {
    ...
    options.AddExpo()
    ...
});

OpenAPI shows the constraints to API consumers. [ExpoValidationPartie] enforces them when requests arrive.

Define a model with validation rules

// The generator automatically creates the validate logic on any classes marked
[Expo]
public partial class CourseRegistrationCommand
{
    // Partie reads the JSON body into this property.
    [FromPayload]
    [IsRequired("A registration payload is required.")]
    public RegistrationPayload? Body { get; init; }
}

[Expo]
public partial class RegistrationPayload
{
    // Reject a missing email, then check its format when present.
    [IsRequired]
    [StringMatchesEmail]
    public string? StudentEmail { get; init; }

    // Course codes need at least two characters.
    [IsRequired]
    [StringHasMinimumLength(2)]
    public string? CourseCode { get; init; }
}

Expo checks nested models too. Each failure identifies the invalid property with a JSON Pointer.

Use Expo without Partie

Without Partie, call TryValidate and choose how your application responds to invalid input:

var payload = new RegistrationPayload
{
    StudentEmail = "student@example.edu",
    CourseCode = "BIO101"
};

// TryValidate returns every failed rule for this object.
if (!payload.TryValidate(out var errors))
{
    foreach (var error in errors)
    {
        Console.WriteLine($"{error.Pointer}: {error.Detail}");
    }
}

What to do next?

Check out installing the Mise system for Database ORM integration!

Database access with Mise

Further Reading

See the Expo guide for custom rules, generated property comparisons and regex rules, collections, nested validation, and error metadata. The repository’s example request shows Expo and Partie binding attributes on the same request model.

Clone this wiki locally