Commands
Arc wraps participating controller commands in a CommandResult or CommandResult<T> envelope. This is not a guarantee about every arbitrary mutation endpoint in an ASP.NET application. The CommandResultOperationTransformer automatically updates the generated operation documentation to reflect this.
What the transformer does
Section titled “What the transformer does”For every endpoint whose controller action or method is identified as a command (not marked with [AspNetResult]), the transformer:
- Replaces the 200 response schema with
CommandResult(forvoid/Taskreturns) orCommandResult<T>(for typed returns). - Adds standard error response schemas for 400, 403, and 500 status codes — all using the same
CommandResult/CommandResult<T>schema so clients only need to handle one type.
Response status codes
Section titled “Response status codes”| Status code | Meaning |
|---|---|
| 200 | Command executed successfully |
| 400 | Validation error or malformed payload |
| 403 | Forbidden — insufficient permissions |
| 500 | Unexpected server error |
Concept return types
Section titled “Concept return types”If the command returns a concept (a type inheriting from ConceptAs<T>), the transformer unwraps the concept to its underlying primitive type before generating the CommandResult<T> schema.
The following type/action fragments illustrate a response contract; place the action inside an existing MVC controller and supply the application service:
public record InvoiceId(Guid Value) : Cratis.Concepts.ConceptAs<Guid>(Value);[HttpPost]public Task<InvoiceId> CreateInvoice(CreateInvoice command, [FromServices] IInvoiceService invoices) => invoices.Create(command);The transformer constructs CommandResult<Guid>; its response member is represented in JSON Schema as a string with UUID format. It does not change a runtime Guid response into a different command contract.
Opting out
Section titled “Opting out”Decorate the action with [AspNetResult] to bypass the transformer and expose the raw return type directly:
[HttpPost][AspNetResult]public Task<InvoiceId> CreateInvoice(CreateInvoice command, [FromServices] IInvoiceService invoices) => invoices.Create(command);