Use a wizard for a bounded submission#
The optional Wizard packages guide an input sequence through details, conditional choices and review to one application-owned final command. CRUD is not required. A wizard is an interaction component; it does not provide a process engine, background worker or durable draft store.
Supply a typed JSON-serializable draft, a trusted WizardDefinition<TDraft>, ordinary Razor fields/review content and an IWizardHandler<TDraft>. Construct the definition during module registration so malformed steps or lifetimes are discovered before a user opens the page. Register the page through normal Shell targets and permission rules.
Define the session and steps#
Definitions contain 2–12 ordered steps. Dependencies refer to earlier steps; the first and last steps are unconditional. Conditional-step values remain in the session, so the final review must explain exclusions and the command must normalize inactive values.
The documented draft bound is 32 KiB at depth 16. Sessions expire after 30 minutes by default, configurable from 1–120 minutes. Expiry prevents editing, advancement and new submission, but must not prevent checking a request already submitted.
Bind ScopeKey to the authenticated subject, application context and journey. Replacing that identity disposes the old session; separate component instances have separate drafts. It is an identity/lifecycle input, not a substitute for server authorization.
| Handler responsibility | Contract |
|---|---|
ValidateAsync |
Read-only validation; a null step requests complete validation |
SubmitAsync |
Authorize and validate again, then durably accept the frozen submission |
GetStatusAsync |
Reauthorize and recover the existing request's outcome |
Next validates the active prefix locally and through the handler. Back never submits. Final submission revalidates every active step and invokes the handler with a frozen snapshot and fresh request ID. Local validation, disabled controls and navigation permission do not authorize the domain command.
Make acceptance recoverable#
Return an accepted WizardReceipt only after durable acceptance. The application should atomically bind subject, context/journey, request ID, payload and business request. Identical replay returns the same operation; a different payload with the same request identity must not produce another operation.
RequestStarted runs before submission and lets the Consumer preserve an opaque request reference. If preservation fails, the command does not run. A reference in a URL can recover the receipt, but it is not a saved draft or permission grant. Keep sensitive draft fields outside URLs and audit records.
An exception or timeout after invocation produces an uncertain state. The wizard does not automatically submit again. Status recovery uses the same request reference; unknown or missing status remains pending because an earlier request may still commit. Cancellation can suppress late UI updates without rolling back remote work. Disable unsafe-method automatic retries throughout the application transport path.
Launch a wizard from CRUD#
EntityPage.ClientActions supplies optional context, record and bounded-selection launch callbacks. Each AdminGridClientAction declares a stable ID, localization key, scope and selection limit. The callback receives copied keys/versions, cancellation and an origin-bound refresh callback, not trusted business-field snapshots.
Reauthorize source and destination during prefill and reload current records. At submission, repeat authorization, validation and concurrency checks. If the operation writes several records atomically, implement that transaction in the domain service. Repeated generic CRUD selection calls do not create a single atomic batch.
Keep the originating grid mounted and refresh it only after confirmed acceptance. A refresh failure must not repeat the command. Domain-service writes do not automatically invoke EF CRUD hooks; use the correct owning service boundary for each path.
Verify the complete interaction#
Exercise invalid steps, conditional values, changed identity, expiry, dirty navigation, a denied direct submission, concurrent updates, accepted-but-lost responses and recovered status after reload. Verify field labels, step/error focus and meaningful review text in the actual Consumer page.
Check the selected release before adopting optional presentation APIs. The guide distinguishes bounded Wizard/CRUD composition from planned application-wide guided-create defaults, post-save actions, uploads and durable drafts. Continue with security and audit for receipt retention and failure policy.