Skip to main content

DTOs & Validators overview

The *Dto class is the attribute-rich UI/API contract for a form-bearing entity (Document/Dictionary/Report/DataProcessor). This is what the Roslyn generators read to emit controllers, client DI wiring, and (for the kinds with generated UI) the Blazor pages themselves — never edit a generated controller or generated .razor file by hand; edit the *Dto and its attributes instead.

Key rules that hold for every *Dto:

  • Optional properties are always nullable types (string?, Guid?, ...); required ones stay non-nullable + [Required]. Nullability, not a parallel convention, is what drives "required vs optional" through client validation, the generated OpenAPI schema, and model binding.
  • Every *Dto is paired with a mandatory *Validator in the same project (KandraWms.Forms for the reference configuration), shared between client and server, even if it just delegates to base.Validate(...). DI validation fails fast at startup if one is missing.
  • Forms-layer code must never reference the server-only Application/Domain/Persistence projects — the Blazor WebAssembly client only ever sees Forms, and pulling in EF Core or server-only services there breaks the client build.

See Generated API Reference for the concrete Dto/Validator catalog once the XML doc sync has run.