liveBook · Manning

TypedResults

As explained in ASP.NET Core in Action, 3e

TypedResults is an ASP.NET Core static helper type that creates typed HTTP responses with common status codes and optional JSON bodies.

TypedResults is a static ASP.NET Core helper type for creating common HTTP responses in minimal API handlers. Its methods can return status codes such as 200, 201, 204, 400, and 404, optionally with a JSON body. section 5.3.1

Results and TypedResults perform the same response-generation work. Results methods return IResult, while TypedResults methods return concrete generic types such as Ok<T>. Those concrete types are especially useful for unit tests and OpenAPI documentation. section 5.3.1

Choose a response helper that matches the outcome of the endpoint:

  • Use TypedResults.Ok(value) for a successful response containing an object. section 5.3.1
  • Use TypedResults.Created(location, value) after creating an entity; it supplies a Location header and response body. section 5.3.1
  • Use TypedResults.NoContent() when the operation succeeds without returning a body. section 5.3.1
  • Use TypedResults or Results helpers for invalid requests and missing entities, commonly with 400 Bad Request or 404 Not Found. section 5.3.1

Fruit endpoint responses

A minimal API can return TypedResults.Ok(fruit) when a fruit is found and TypedResults.Created($"/fruit/{id}", fruit) after adding one. The same handlers can return Results.NotFound() when the identifier is missing or Results.BadRequest(...) when it already exists. section 5.3.1

Listing 5.3 Using Results and TypedResults in a minimal API
using System.Collections.Concurrent;
 
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
WebApplication app = builder.Build();
 
var _fruit = new ConcurrentDictionary<string, Fruit>();        #1
 
app.MapGet("/fruit", () => _fruit);
 
app.MapGet("/fruit/{id}", (string id) =>
    _fruit.TryGetValue(id, out var fruit)                      #2
        ? TypedResults.Ok(fruit)                               #3
        : Results.NotFound());                                 #4
 
 
app.MapPost("/fruit/{id}", (string id, Fruit fruit) =>
    _fruit.TryAdd(id, fruit)                                   #5
        ? TypedResults.Created($"/fruit/{id}", fruit)          #6
        : Results.BadRequest(new                               #7
            { id = "A fruit with this id already exists" }));  #7
 
app.MapPut("/fruit/{id}", (string id, Fruit fruit) =>
{
 
    _fruit[id] = fruit;
    return Results.NoContent();                                #8
});
 
app.MapDelete("/fruit/{id}", (string id) =>
{
    _fruit.TryRemove(id, out _);                               #9
    return Results.NoContent();                                #9
});
 
app.Run();
record Fruit(string Name, int stock);
#1 Uses a concurrent dictionary to make the API thread-safe
#2 Tries to get the fruit from the dictionary. If the ID exists in the dictionary, this returns true . . .
#3 . . . and we return a 200 OK response, serializing the fruit in the body as JSON.
#4 If the ID doesn’t exist, returns a 404 Not Found response
#5 Tries to add the fruit to the dictionary. If the ID hasn’t been added yet. this returns true . . .
#6 . . . and we return a 201 response with a JSON body and set the Location header to the given path.
#7 If the ID already exists, returns a 400 Bad Request response with an error message
#8 After adding or replacing the fruit, returns a 204 No Content response
#9 After deleting the fruit, always returns a 204 No Content response

Use the complete fruit API listing to compare successful, creation, missing-resource, and validation responses in one runnable minimal API. section 5.3.1

For files, byte arrays, or streams, use the corresponding Results or TypedResults helpers when available. For unusual responses, inject HttpResponse and write the response manually; repeated custom behavior can become a custom IResult type. section 5.3.4

How ASP.NET Core in Action, 3e covers it

How deep it goes
Explains status-code usage, concrete return types, and endpoint examples, but defers custom response implementation.
Examples
Demonstrates fruit CRUD responses, including Ok, Created, NotFound, and BadRequest results.
What it assumes
Assumes familiarity with minimal API endpoint handlers and HTTP response status codes.
What you can do after
Apply it via TypedResults in minimal API handlers to return typed success and error responses.
How it connects
Connects TypedResults with minimal APIs, HTTP status codes, IResult, unit testing, OpenAPI, and Problem Details.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of ASP.NET Core in Action, 3e. The section links point to the parts of the book it draws on.