# Web APIs

Web APIs use the MVC framework of ASP.NET Core.

APS.NET

Before the Core, ASP.NET's MVC and Web APIs stacks were separate.

The default Program.cs looks like this:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

A controller example:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet(Name = "GetWeatherForecast")]
    public IEnumerable<WeatherForecast> Get()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = "Some summary"
        })
        .ToArray();
    }
}

The ControllerBase has a bunch of useful methods, like the ones that return different kinds of IActionResult.

The ApiController attribute applies some useful conventions to the controller (e.g. the usage of ProblemDetails).

Controller

There is also a Controller base class, but it's more useful for MVC controllers that return Razor views (btw, Razor Pages are a better alternative).

# Routing

We can use exactly the same templates as in the Razor Pages routing. However, we speify those in a different place - in the action's Route attribute.

public class WeatherForecastController : ControllerBase
{
   [Route("")]
    public IEnumerable<WeatherForecast> Get()
    {
        // ...
    }
}

We can define multiple Routes per action. We can define Route on the controller and the actions. In such a case, the action's URL is a combination of these two. We can sign out of that by prefixing action's Route with a /. Then, the action's Route is the URL.

Token Replacement

We can also include tokens [controller] and [action] in the routing templates to include the name of controller/action in the URL.

# HTTP Verb

Oura actions may also be marked with HTTP method to be used. We do that with attributes:

  • HttpPost
  • HttpGet
  • HttpPut
  • HttpDelete
  • etc.

TIP

These attributes can be used instead of Route since they also accept the route template.

# ApiController attribute

The following features are introduced with the ApiController attribute:

  • complex action parameters are assumed to be FromBody and we don't need to use that attribute. By default, form would be expected.
  • the ModelState.IsValid is executed automatically (via a filter) and 400 is returned in case it fails.
  • The error status code are automatically converte to the ProblemDetails convention.

ProblemDetails

ProblemDetails payloads will be returned only if the request exection actually goes into some controller's action. If an error is found earlier (or exception is thrown in the action), the HTTP response will not follow the ProblemDetails convention. One solution could be to use the Hellang.Middleware.ProblemDetails (opens new window) package.

# Returning data

We can return data from actions directly (e.g. return new ["a", "b", "c"]) or we can return some IActionResult. In the first case it would be the same as returning an OkResult with the Ok() helper.

# Formats

By default, ASP.NET Core returns data in JSON format. We can change that by adding additional providers. For example, to add text/xml support:

builder.Services.AddControllers().AddXmlSerializerFormatters();

TIP

The same way, we can also add input providers to support different kinds of formats in requests.

Last Updated: 3/12/2023, 5:06:29 PM