HTTP Overview and the Bridge to ASP.NET Core
Before we can talk about ASP.NET Core, we should at least discuss the major parts of HTTP so we can know how each of those things fit into bigger picture.
What is HTTP?
HTTP is a protocol that allows clients to communicate with servers. It's the protocol that powers the web.
Let's take a brief look at a typical request/response
This is an example GET request sent from a client to a server:
GET /index.html HTTP/1.1
Host: www.example.com
Accept: text/html
Accept-Language: en-US
Deconstructing the request, line-by-line:
Line | Description |
---|---|
GET /index.html HTTP/1.1 |
This is the request line. It specifies the HTTP method (GET), the resource being requested (/index.html), and the HTTP version (1.1). |
Host: www.example.com |
The Host header specifies the domain name of the server (virtual host) to which the request is being sent. |
Accept: text/html |
The Accept header tells the server what content types the client is able to understand. In this case, it's requesting HTML content. |
Accept-Language: en-US |
This header indicates the natural language and locale that the client prefers. Here, it's specifying US English. |
The response:
HTTP/1.1 200 OK
Content-Type: text/html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
etc...
The response has the following parts:
Line | Description |
---|---|
HTTP/1.1 200 OK |
This is the status code line. It indicates the HTTP version (1.1), the status code (200), and a short phrase describing the status (OK). |
Content-Type: text/html |
This header specifies the MIME type of the response body, indicating that the response content is HTML. |
The body of the response contains the HTML content of the requested page.
HTTP Methods
Also known as HTTP verbs, these are the methods that browsers use to tell the server what they want to do.
GET
: Requests a representation of the specified resource.POST
: Submits an entity to the specified resource, often causing a change in state or side effects on the server.PUT
: Replaces the specified resource with the request payload.DELETE
: Deletes the specified resource.
These status code are used, but not as often, and won't be covered in this course.
PATCH
: Applies partial modifications to a resource.HEAD
: Asks for a response identical to that of a GET request, but without the response body.OPTIONS
: Describes the communication options for the target resource.
Most of the time, people are using the top four, GET, POST, PUT, and DELETE.
HTTP Status Codes
Status codes are three-digit codes that indicate the result of a request. They are separated into five classes:
- 1xx: Informational - Request received, continuing process
- 2xx: Success - The action was successfully received, understood, and accepted
- 3xx: Redirection - Further action must be taken in order to complete the request
- 4xx: Client Error - The request contains bad syntax or cannot be fulfilled
- 5xx: Server Error - The server failed to fulfill an apparently valid request
The most common status codes for this course are:
Code | Description |
---|---|
200 | OK - The request was successful |
201 | Created - A new resource was successfully created |
400 | Bad Request - The request is invalid |
401 | Unauthorized - Authentication is required |
403 | Forbidden - Access is forbidden |
404 | Not Found - The requested resource was not found |
500 | Internal Server Error - The server encountered an error |
Let's look at a POST request real fast
The request we made above lacked what's called a body - a way to send data to the server. GET
requests don't support bodies, but POST
does.
Here's an example of a POST
request:
POST /employees/create HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"name": "John Doe",
"email": "john.doe@example.com",
"message": "Hello, world!"
}
In this request:
- The
POST
method is used to submit data to the server. - The
Content-Type
header specifies the MIME type of the request body, indicating that the request content is JSON. - The request body contains the data to be submitted to the server.
What is ASP.NET Core?
ASP.NET Core is a framework for building web applications and APIs. It's built on the .NET runtime and is designed to be a high-performance, modular web framework.
You're one command away from creating a new ASP.NET Core project:
dotnet new webapi -n MyWebApp
This will create a new web API project in the MyWebApp
directory.
Here's the Program.cs file that is generated:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();
app.Run();
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
Let's deconstruct it right quick:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
This part of the file is used to configure the services that the application will use.
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
This part of the file is used to configure the HTTP request pipeline. Any place where the API starts with "Use" or "Get" will typically be adding something to the HTTP middleware pipeline. In this case, it's checking if the application is in development mode and if so, it's adding the Swagger and Swagger UI services to the application middleware pipeline.
Swagger?
Swagger is a tool that allows us to document our API. It's what we're using to generate the API documentation you see in the browser. Very useful for API developers!
It generates something that looks like this when you start the app:
Wait, what the heck is middleware?
Middleware are the things that handle HTTP requests and responses in ASP.NET Core.
Source: ASP.NET Docs
Let's dive into the Swagger source code and see for ourselves:
/// <summary>
/// Register the Swagger middleware with provided options
/// </summary>
public static IApplicationBuilder UseSwagger(this IApplicationBuilder app, SwaggerOptions options)
{
return app.UseMiddleware<SwaggerMiddleware>(options);
}
This is the Swagger middleware, which is used to serve the Swagger UI and the generated JSON documentation. Watch the video to see how this is deconstructed!
Adding our own middleware to prove a point
Let's add some middleware to our pipeline to prove a point: the middleware is always in control.
After the Swagger calls, we'll add this middleware:
app.Use(async (HttpContext context, RequestDelegate next) =>
{
context.Response.Headers.Append("Content-Type", "text/html");
await context.Response.WriteAsync("<h1>Welcome to Ahoy!</h1>");
});
This middleware will skip the rest of the pipeline and write its own goodies to the response.
Ok, but what is HttpContext
?
HttpContext
is the main class that represents the incoming HTTP request - and all related things around handling that request - in ASP.NET Core. It's the main object that is passed around in the middleware pipeline.
It contains all the information about the request and response.
Here are the most important properties of each:
Property | Description |
---|---|
Request |
The request object |
Response |
The response object |
Items |
A dictionary of items that can be used to store data during the request/response process |
User |
The user object - we'll discuss this more when we get to authentication |
Features |
A collection of features that can be used to store data or add behaviors to the request/response process |
The Request
and Response
properties are the most important ones, as they are the ones that contain the request and response data.
For instance, Request
contains the request headers, the request method, the request URL, the request body, etc.
Most of Spencer's time is spent reading the Request
or User
objects.
Continuing the breakdown
We took an off ramp but we're back on the highway:
app.UseHttpsRedirection();
This is the middleware that redirects HTTP requests to HTTPS. It's not strictly speaking required for this course, but it's good practice to have in so tha you use HTTPS as much as possible.
var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();
This is the middleware that handles the GET request for the /weatherforecast
endpoint. As you can see, all it does is return some random data with weather forecasts.
The .WithName
and .WithOpenApi
methods are used to add metadata that OpenAPI uses to generate the documentation.
app.Run();
This is where the app actually starts. After you've registered all of your services and middleware, you call app.Run()
to start the application.