Skip to content
Development
Skill

/csharp-api-controller-standards

Defines the coding standards, patterns, and conventions for ASP.NET Core REST API controllers. Rules cover routing, HTTP verbs, response types, XML documentation, dependency injection, and asynchronous execution. Apply these rules uniformly to ensure a consistent, predictable,

From plugin
ai-playbook
73 skills

Claude Code

$ npx -y skills add linuxchata/ai-playbook --skill csharp-api-controller-standards --agent claude-code

SKILL.md

csharp-api-controller-standards.SKILL.md
name: csharp-api-controller-standards
description: Defines the coding standards, patterns, and conventions for ASP.NET Core REST API controllers. Rules cover routing, HTTP verbs, response types, XML documentation, dependency injection, and asynchronous execution. Apply these rules uniformly to ensure a consistent, predictable, and well-documented API surface.
metadata:
  version: 1.0.0

C# ASP.NET Core API Controller Standards

Description

Defines the coding standards, patterns, and conventions for ASP.NET Core REST API controllers. Rules cover routing, HTTP verbs, response types, XML documentation, dependency injection, and asynchronous execution. Apply these rules uniformly to ensure a consistent, predictable, and well-documented API surface.

---

1. Controller Structure & Inheritance

1.1 Base Class and Attributes

  • All API controllers must inherit from `ControllerBase` (not `Controller`, which includes view rendering logic).
  • Decorate all controllers with the `[ApiController]` attribute to enable automatic model validation, API behavior conventions, and attribute routing requirements.
  • Use the `[Route]` attribute at the class level to define the base path.
// ✅ Correct
[ApiController]
[Route("api/[controller]")]
public sealed class OrdersController : ControllerBase
{
}

// ❌ Wrong
public class OrdersController : Controller { }

---

2. Routing Conventions

2.1 Resource Naming

  • Use **nouns**, not verbs, for endpoint paths.
  • Prefer `[controller]` in the `Route` attribute to automatically use the controller name (minus the "Controller" suffix).

2.2 Route Parameters

  • Specify route parameters explicitly in the HTTP verb attributes.
  • Match route parameter names exactly with the method parameter names.
[HttpGet("{id:guid}")]
public async Task<IActionResult> GetByIdAsync(Guid id, CancellationToken cancellationToken)

---

3. HTTP Methods & Attributes

3.1 Standard Verbs

Use the correct HTTP verb corresponding to the operation:

| Verb | Usage | Idempotent | |---|---|---| | `[HttpGet]` | Retrieve a resource or collection | Yes | | `[HttpPost]` | Create a new resource or execute an action | No | | `[HttpPut]` | Fully update an existing resource | Yes | | `[HttpPatch]` | Partially update an existing resource | No | | `[HttpDelete]` | Remove a resource | Yes |

3.2 Action Parameters Binding

Explicitly state where parameters are bound from to avoid ambiguity and improve OpenAPI generation:

  • `[FromRoute]`: For IDs and path segments.
  • `[FromQuery]`: For filtering, paging, and sorting parameters.
  • `[FromBody]`: For complex objects in POST/PUT/PATCH requests.
[HttpGet("{id:guid}/items")]
public async Task<IActionResult> GetItemsAsync(
    [FromRoute] Guid id, 
    [FromQuery] int page, 
    CancellationToken cancellationToken)

---

4. Responses & Status Codes

4.1 Explicit Action Results

  • Return `IActionResult` or `ActionResult<T>`.
  • Use the built-in helper methods (`Ok()`, `Created()`, `NotFound()`, `BadRequest()`, `NoContent()`) to generate responses.

4.2 Standard Status Codes

Always return the appropriate HTTP status code for the outcome:

  • **200 OK**: Successful GET.
  • **201 Created**: Successful POST that creates a resource. Might include a `Location` header pointing to the new resource.
  • **204 No Content**: Successful operation that returns no body (e.g., DELETE, PUT, PATCH).
  • **400 Bad Request**: Client error (validation failure, invalid input).
  • **401 Unauthorized**: Authentication required.
  • **403 Forbidden**: Authenticated, but lacks permission.
  • **404 Not Found**: The requested resource ID does not exist.
  • **409 Conflict**: Resource state conflict (e.g., trying to create a duplicate).
[HttpPost]
public async Task<IActionResult> CreateAsync([FromBody] CreateOrderRequest request, CancellationToken cancellationToken)
{
    var id = await _service.CreateAsync(request, cancellationToken);
    return CreatedAtAction(nameof(GetByIdAsync), new { id = id }, request);
}

4.3 `[ProducesResponseType]`

Explicitly declare all possible status codes and their corresponding return types using `[ProducesResponseType]`. This is critical for generating accurate OpenAPI/Swagger documentation.

[HttpGet("{id:guid}")]
[ProducesResponseType(typeof(OrderDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetByIdAsync([FromRoute] Guid id, CancellationToken cancellationToken)

---

5. XML Documentation

5.1 Public API Contracts

Every controller action must be fully documented using XML comments.

XML comment tags:

  • `<summary>`: A brief, single-sentence description of what the endpoint does.
  • `<remarks>`: (Optional) Detailed information, usage examples, or nuances.
  • `<param>`: Description of each input parameter.
  • `<returns>`: Description of the HTTP response.
  • `<response>`: Description of each possible HTTP status code returned.
/// <summary>
/// Retrieves a specific order by its unique identifier.
/// </summary>
/// <param name="id">The unique identifier of the order.</param>
/// <param name="cancellationToken">A cancellation token.</param>
/// <returns>The HTTP response.</returns>
/// <response code="200">A specific order.</response>
/// <response code="404">If the order is not found.</response>
[HttpGet("{id:guid}")]
[ProducesResponseType(typeof(OrderDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetByIdAsync([FromRoute] Guid id, CancellationToken cancellationToken)
{
    // ... implementation
}

---

6. Dependency Injection

6.1 Constructor Injection

Always use constructor injection for services required by the controller.

**If using C# 12 or later**, prefer **Primary Constructors** to eliminate boilerplate:

// ✅ Correct (C# 12+)
[ApiController]
[Route("api/[controller
Read more
@linuxchata
Ships withai-playbook

Rules, skills, and guidelines for AI coding assistants – Claude, Cursor, and beyond.

Stars on GitHub

Momentum

stars in total
7
Star history of linuxchata/ai-playbook on GitHub, a chart by star-history.com

Other skills on ai-playbook.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about csharp-api-controller-standards.

Which coding agents can use csharp-api-controller-standards?
csharp-api-controller-standards installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.