liveBook · Manning

Content negotiation

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

Content negotiation is the process by which an HTTP client and server select a representation format for a response based on supported media types and request preferences.

Content negotiation lets an HTTP API return a representation its client can understand. The client lists acceptable media types in the request’s Accept header; the server chooses a format it can produce and identifies it in the response’s Content-Type header. Accept can include preferences: application/json,text/xml;q=0.9 prefers JSON over XML. section 20.5

Requesting a list as XML

A web API controller returns a list of car names. Without an XML formatter, a request with Accept: text/xml still gets JSON. After XML formatters are added, the same request gets an XML response. The action returns data; formatters handle its representation. section 20.5 section 20.5.1

services.AddControllers()
   .AddXmlSerializerFormatters();

AddXmlSerializerFormatters() enables XML responses for controllers. It also enables XML request bodies; without an XML input formatter, those requests receive 415 Unsupported Media Type. section 20.5.1

ASP.NET Core web API controllers have a few defaults worth checking:

  • Available response types initially include application/json, text/plain, and text/html; additional output formatters can add other types. section 20.5.2
  • With no Accept header, a returned string is text/plain. For other models, the first suitable formatter is used, typically producing JSON; that fallback also applies when none of the requested formats is supported. section 20.5.2
  • Returning a null API model produces 204 No Content by default. section 20.5.2
  • A browser-style Accept header containing */* bypasses negotiation by default, usually producing JSON. section 20.5.2
Listing 20.14 Customizing MVC to respect the browser’s Accept header in web APIs
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
 
builder.Services.AddControllers(options =>                           #1
{
    options.RespectBrowserAcceptHeader = true;                       #2
    options.OutputFormatters.RemoveType<StringOutputFormatter>();    #3
});
#1 AddControllers has an overload that takes a lambda function.
#2 False by default; several other properties are also available to be set.
#3 Removes the output formatter that formats strings as text/plain

If browser requests need to follow their Accept header, set RespectBrowserAcceptHeader to true when registering controllers. The listing also removes the formatter that otherwise returns strings as text/plain. section 20.5.2

Choose web API controllers when built-in, extensible negotiation of formats such as JSON and XML matters. Minimal APIs automatically serialize responses only as JSON; negotiation is not built in, though it can be added separately. section 20.5 section 20.6

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

How deep it goes
Explains headers, formatter defaults, browser exceptions, and configuration while deferring custom formatter construction.
Examples
Tests a car-list response requested as XML, then shows XML formatter registration and browser Accept configuration.
What it assumes
Builds on controller actions and API models while defining the relevant HTTP headers and Accept preferences.
What you can do after
Operate/configure it by adding XML formatters and changing how ASP.NET Core controllers handle browser Accept headers.
How it connects
Connects HTTP Accept and Content-Type headers to output formatters, XML serialization, web API controllers, and minimal APIs.

Also explained in

Compare how 3 books explain content negotiation →

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.