CodingNeed.

2 · Data and boundaries · 30 MIN

DTO validation at an API boundary

A deserialized DTO still needs explicit domain validation.

Model binding reads a JSON body into the input record, but it does not establish every business rule. In this .NET 8 minimal API example, the delegate explicitly checks a trimmed title and weekly goal. Later framework versions may offer additional validation facilities, so keep the target version clear. A preview response avoids implying persistence. Before storing an account-owned plan, authenticate the caller, derive its owner ID from the session and check authorization on the server.

Check title and goal boundaries.

Read the example

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
var app = WebApplication.CreateBuilder(args).Build();
app.MapPost("/preview", (PlanInput input) => {
  var title = input.Title?.Trim();
  if (title is null || title.Length < 3 || title.Length > 80 || input.WeeklyGoal < 1 || input.WeeklyGoal > 20)
    return Results.BadRequest(new {error="Invalid title or weekly goal"});
  return Results.Ok(new {title,weeklyGoal=input.WeeklyGoal});
});
app.Run();
public sealed record PlanInput(string? Title, int WeeklyGoal);
Check the expected output
A valid body returns a trimmed preview; invalid title or weekly goal returns 400.

Your challenge

Add field-specific validation errors and enforce a request-body size limit; document whether unknown JSON fields are accepted or rejected.

Solution cost: O(m) title processing. time · O(m) input and trimmed string. space

Common trap

A non-nullable C# annotation does not establish that an HTTP client supplied a valid value.

Study the project implementation
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
var app = WebApplication.CreateBuilder(args).Build();
app.MapPost("/preview", (PlanInput input) => {
  var title = input.Title?.Trim();
  if (title is null || title.Length < 3 || title.Length > 80 || input.WeeklyGoal < 1 || input.WeeklyGoal > 20)
    return Results.BadRequest(new {error="Invalid title or weekly goal"});
  return Results.Ok(new {title,weeklyGoal=input.WeeklyGoal});
});
app.Run();
public sealed record PlanInput(string? Title, int WeeklyGoal);

Further reading: Official documentation

Next lesson: Authentication and authorization are different checks

Essential cookies keep your account signed in. Optional analytics is not configured on this site. Your choice does not affect access to lessons.

Read the Privacy Policy. You can change this choice in the footer.