Skip to main content
The Intent.AspNetCore.Controllers module generates ASP.NET Core Controller classes based on services modeled in the Services Designer. It creates fully-featured REST API controllers with proper routing, parameter binding, and response handling.

Overview

This module bridges the gap between your service definitions in the Services Designer and production-ready ASP.NET Core controllers. It automatically generates controllers with appropriate HTTP verbs, route configurations, and integration with your application layer.

What Gets Generated

Controller Classes

For each service in your Services Designer, a corresponding controller is generated:
[ApiController]
[Route("api/[controller]")]
public class CustomersController : ControllerBase
{
    private readonly ICustomerService _customerService;

    public CustomersController(ICustomerService customerService)
    {
        _customerService = customerService;
    }

    [HttpGet("{id}")]
    [ProducesResponseType(typeof(CustomerDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<CustomerDto>> GetById(
        [FromRoute] Guid id, 
        CancellationToken cancellationToken)
    {
        var result = await _customerService.GetByIdAsync(id, cancellationToken);
        return result != null ? Ok(result) : NotFound();
    }

    [HttpPost]
    [ProducesResponseType(typeof(Guid), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<ActionResult<Guid>> Create(
        [FromBody] CreateCustomerDto dto, 
        CancellationToken cancellationToken)
    {
        var id = await _customerService.CreateAsync(dto, cancellationToken);
        return CreatedAtAction(nameof(GetById), new { id }, id);
    }
}

Additional Components

  • ExceptionFilter: Global exception handling for controllers
  • BinaryContentFilter: Handles file upload/download scenarios
  • JsonResponse: Custom response types for JSON serialization

Key Features

Automatic Routing

RESTful routes generated from your service operations

HTTP Verb Mapping

Smart mapping of operations to GET, POST, PUT, DELETE

Parameter Binding

Correct [FromRoute], [FromBody], [FromQuery] attributes

Response Types

ProducesResponseType attributes for OpenAPI documentation

Module Settings

Configure controller generation through application settings:

Default API Security

Default API Security
select
default:"unsecured"
Whether controllers are secured or not by defaultOptions:
  • secured - Apply [Authorize] attribute by default
  • unsecured - No authorization required by default

Default API Route Prefix

Default API Route Prefix
text
default:"api/"
API route prefix for newly created services

Serialize Enums as Strings

Serialize Enums as Strings
boolean
default:"false"
Configures whether to serialize/deserialize enums as strings instead of integers

Ignore JSON Reference Cycles

On Serialization ignore JSON reference cycles
boolean
default:"false"
Controls whether to ignore JSON reference cycles during serialization

Service Designer Integration

The module reads service definitions from the Services Designer:
1

Define Services

Create services in the Services Designer with operations
2

Configure Operations

Set HTTP verbs, routes, and parameters for each operation
3

Run Software Factory

Controllers are automatically generated
4

Customize

Extend generated controllers using partial classes

Dispatch Strategies

The Controllers module supports different dispatch patterns:

MediatR Dispatch

When Intent.Application.MediatR is installed, controllers dispatch to MediatR handlers:
[HttpGet("{id}")]
public async Task<ActionResult<CustomerDto>> GetById(
    [FromRoute] Guid id, 
    CancellationToken cancellationToken)
{
    var result = await _mediator.Send(
        new GetCustomerByIdQuery { Id = id }, 
        cancellationToken);
    return Ok(result);
}

Service Contract Dispatch

When Intent.Application.Contracts is installed, controllers inject service interfaces:
private readonly ICustomerService _service;

[HttpGet("{id}")]
public async Task<ActionResult<CustomerDto>> GetById(
    [FromRoute] Guid id, 
    CancellationToken cancellationToken)
{
    var result = await _service.GetByIdAsync(id, cancellationToken);
    return Ok(result);
}

Controller Stereotypes

Apply stereotypes in the Services Designer to customize controller behavior:

HTTP Settings

  • Route: Custom route template
  • Verb: Override default HTTP verb
  • Return Type: Specify response status codes

Security

  • Secured: Require authentication
  • Authorize: Require specific roles or policies
  • AllowAnonymous: Allow unauthenticated access

Example: CRUD Controller

Generated controller for a complete CRUD service:
[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
    private readonly IProductService _service;

    public ProductsController(IProductService service)
    {
        _service = service;
    }

    [HttpGet]
    [ProducesResponseType(typeof(List<ProductDto>), 200)]
    public async Task<ActionResult<List<ProductDto>>> GetAll(
        CancellationToken cancellationToken)
    {
        var results = await _service.GetAllAsync(cancellationToken);
        return Ok(results);
    }

    [HttpGet("{id}")]
    [ProducesResponseType(typeof(ProductDto), 200)]
    [ProducesResponseType(404)]
    public async Task<ActionResult<ProductDto>> GetById(
        [FromRoute] Guid id,
        CancellationToken cancellationToken)
    {
        var result = await _service.GetByIdAsync(id, cancellationToken);
        return result != null ? Ok(result) : NotFound();
    }

    [HttpPost]
    [ProducesResponseType(typeof(Guid), 201)]
    [ProducesResponseType(400)]
    public async Task<ActionResult<Guid>> Create(
        [FromBody] CreateProductDto dto,
        CancellationToken cancellationToken)
    {
        var id = await _service.CreateAsync(dto, cancellationToken);
        return CreatedAtAction(nameof(GetById), new { id }, id);
    }

    [HttpPut("{id}")]
    [ProducesResponseType(204)]
    [ProducesResponseType(400)]
    [ProducesResponseType(404)]
    public async Task<ActionResult> Update(
        [FromRoute] Guid id,
        [FromBody] UpdateProductDto dto,
        CancellationToken cancellationToken)
    {
        await _service.UpdateAsync(id, dto, cancellationToken);
        return NoContent();
    }

    [HttpDelete("{id}")]
    [ProducesResponseType(204)]
    [ProducesResponseType(404)]
    public async Task<ActionResult> Delete(
        [FromRoute] Guid id,
        CancellationToken cancellationToken)
    {
        await _service.DeleteAsync(id, cancellationToken);
        return NoContent();
    }
}

Installation

Intent.AspNetCore.Controllers

Dependencies

  • Intent.AspNetCore (>= 6.0.8)
  • Intent.Common.CSharp
  • Intent.Metadata.WebApi
  • Intent.Modelers.Services

Next Steps

MediatR Dispatch

Dispatch to MediatR command/query handlers

Swashbuckle

Generate OpenAPI documentation

Versioning

Add API versioning support

CORS

Configure cross-origin requests

Build docs developers (and LLMs) love