This product is not supported for your selected Datadog site. ().

Metadata

ID: csharp-best-practices/annotate-producesresponsetype

Language: C#

Severity: Info

Category: Best Practices

Description

This rule ensures that API methods explicitly document their response types using attributes like ProducesResponseType. By clearly specifying the type of data returned and the corresponding HTTP status codes, the API becomes more self-descriptive and easier to understand for both developers and automated tools.

Explicitly documenting response types improves API discoverability and helps client code generators produce accurate models. It also enhances maintainability by making the expected outputs of each endpoint clear, reducing ambiguity and potential bugs during integration or testing phases.

To comply with this rule, always annotate your controller methods with ProducesResponseType attributes that specify the response type and status code, especially when returning IActionResult or similar abstractions. For example, use [ProducesResponseType(typeof(Customer), StatusCodes.Status200OK)] alongside other relevant status codes to clearly communicate the possible responses. Alternatively, returning a strongly typed ActionResult<T> can also implicitly document the response type.

Non-Compliant Code Examples

public class Foo {
    [HttpGet("{id}")]
    public Task<IActionResult> method(int id)
    {
        var customer = _repository.GetById(id);
        if (customer == null)
            return NotFound();

        return Ok(customer);
    }
}
public class Foo {
    [HttpGet("{id}")]
    public IActionResult GetCustomer(int id)
    {
        var customer = _repository.GetById(id);
        if (customer == null)
            return NotFound();

        return Ok(customer);
    }
}

Compliant Code Examples

public class Foo {
    [HttpGet("{id}")]
    [ProducesResponseType(typeof(Customer), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public Task<IActionResult> GetCustomer(int id)
    {
        var customer = _repository.GetById(id);
        if (customer == null)
            return NotFound();

        return Ok(customer);
    }
}
public class Foo {
    [HttpGet("{id}")]
    public ActionResult<Customer> GetCustomer(int id)
    {
        var customer = _repository.GetById(id);
        if (customer == null)
            return NotFound();

        return customer; // Automatically infers ProducesResponseType<Customer>(200)
    }
}
public class Foo {
    [HttpGet("{id}")]
    [ProducesResponseType(typeof(Customer), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public IActionResult GetCustomer(int id)
    {
        var customer = _repository.GetById(id);
        if (customer == null)
            return NotFound();

        return Ok(customer);
    }
}
https://static.datadoghq.com/static/images/logos/github_avatar.svg https://static.datadoghq.com/static/images/logos/vscode_avatar.svg jetbrains

Seamless integrations. Try Datadog Code Security