# Validation and Error Responses — .NET Core: Build, Test and Ship Web APIs

Source: https://www.geekswithgeeks.com/en/dotnet-core/sec-validation-errors

> Reject bad input with 400 and return consistent ProblemDetails errors.

## Never trust input

Treat every request body as untrusted. Check required fields and ranges, and return `400 Bad Request` with a clear message. `ProblemDetails` (RFC 9457) is the standard JSON shape for errors, so clients can parse them uniformly.

## Validate, protect, verify

Bad input is rejected, protected routes check identity, and tests prove the behaviour.

![Four stages: validate, authenticate, authorize, test.](assets/figures/dotnet-core/section-7-map.svg) — Figure 7.1 — Validate, authenticate, authorize, test.

## Manual validation and a global handler

`Results.ValidationProblem` returns a 400 with field errors. `AddProblemDetails` plus `UseExceptionHandler` turns unhandled exceptions into a safe 500 response without a stack trace.

```csharp
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();

app.MapPost("/books", (Book b) =>
{
    var errors = new Dictionary<string, string[]>();
    if (string.IsNullOrWhiteSpace(b.Title)) errors["title"] = ["Title is required."];
    if (b.Price < 0) errors["price"] = ["Price cannot be negative."];
    return errors.Count > 0 ? Results.ValidationProblem(errors) : Results.Ok(b);
});
```

## Do not leak internals

Return friendly messages and a correlation ID, not exception text, SQL or file paths. Log the details on the server where attackers cannot read them.

**Quiz:** Which status code fits "your JSON has an invalid field"?

- [ ] 500 Internal Server Error
- [ ] 200 OK
- [x] 400 Bad Request
- [ ] 301 Moved Permanently

*Answer:* 400 Bad Request. 400 means the client sent something invalid. 500 is reserved for server faults.
