In the How the Web Works series of lessons from the weekend homework, we learned how websites and applications communicate with users' clients to display their content in the browser. We discussed clients and servers, uniform resource locators (URLs), server-side MVC patterns, and the request-response loop.
Now that we've created several applications that handle HTTP requests and responses through controller routes, let's dive deeper. This lesson will review the general request-response loop we learned earlier this section and also discuss new HTTP methods that will shed light on how MVC routes work. Concepts discussed here are essential to understanding the more advanced routing we'll learn later in this section, so follow along carefully and revisit this lesson as necessary.
First, let's walk through the request-response loop we learned about previously, discussing in greater detail how it works with ASP.NET Core MVC applications.
To access a page on a website, including one made with ASP.NET MVC, the user either types in the site's URL, clicks a link, or submits a form. The client makes a request to the server that hosts the site. As we learned earlier this section, this request follows strict formatting rules called HTTP, or Hypertext Transfer Protocol. Specifically, HTTP requests from the client include four elements that will be sent to the server:
HTTP methods, also known as verbs, indicate the type of action the client is requesting the server to complete. The most common HTTP methods are GET and POST.
Requests with GET methods retrieve resources from the server. For example, when we navigate to the Learn How to Program Courses page the client requests the resource at the URL https://www.learnhowtoprogram.com/courses
. The server locates the content corresponding to the /courses
URL path and sends it back to the client in a response. Our client essentially went out and got the necessary resources to render a page.
Unlike GET requests, POST requests actually aim to change something on the website's server. This includes adding, updating or deleting items.
For instance, when we like a friend's photo on social media, our client is sending a POST request because we're changing something on that site's server. We're both increasing the total number of likes recorded on that photo and adding our username to the list of those that like the picture.
In the last lesson, we added this attribute to our to do list form:
method="post"
We did this because we wanted to add an Item
.
In addition to an HTTP method, the client's request to the server also includes a path. The path identifies the web resource that should be retrieved (GET) or acted on (POST). In the example https://www.learnhowtoprogram.com/courses
the resource /courses
is known as the path.
If we were visiting the form in our to do list application, /items/new
is the path.
Headers are also part of the request message protocol. They provide the server with more information about the client, the server and the request. Here are some examples of header fields included in a request message:
www.learnhowtoprogram.com
and localhost:5000
.There's no need to worry about headers too much yet. But for a list of all available request headers, check out the HTTP Headers Wikipedia article.
HTTP Requests also include a body. The body contains any data (beyond the URL and headers) that must be transmitted to the server.
For example, when a user submits the form in our to do list, the resulting POST request needs to include the specific information they typed in the form so the server can store this information as a new Item
and later print it to our list. This data is delivered to the server in the body of the request.
Remember, we can view HTTP requests and responses right in Chrome's developer tools:
$ dotnet build
and $ dotnet run
.localhost:5000
and open developer tools (Command + Option + J on Mac or Ctrl + Shift + I on PC).After the client sends a request, the server receives it. The HTTP method and path are matched to a route in the controller.
The controller is then responsible for bringing view data and class methods together. In our MVC applications, route decorators state the path that corresponds to each:
...
[Route("/")]
...
[Route("/items/new")]
...
[Route("/items")]
...
...
For example, users can click a link on our homepage to see a form. When they click on this link, a request is created and sent to our application's server. That request includes the path "/items/new"
.
Our application server can identify what resource should be retrieved and sent back in its response by matching this path to the route in our controller that has the same path specified in the route decorator. It then executes that route's code.
So far, we have used the syntax [Route("route-name")]
to declare paths for each route in our controller. Now that we know what GET
and POST
indicate, we'll begin using a different, more specific annotation for defining the routes for methods. We'll use [HttpGet("route-name")]
for GET
methods and [HttpPost("route-name")]
for POST
methods.
Our updated HomeController.cs
looks like this:
using Microsoft.AspNetCore.Mvc;
using ToDoList.Models;
namespace ToDoList.Controllers
{
public class HomeController : Controller
{
[HttpGet("/")]
public ActionResult Index()
{
Item starterItem = new Item("Add first item to To Do List");
return View(starterItem);
}
[HttpGet("/items/new")]
public ActionResult CreateForm()
{
return View();
}
[HttpPost("/items")]
public ActionResult Create(string description)
{
Item myItem = new Item(description);
return View("Index", myItem);
}
}
}
After the client creates and sends a request and our server matches the path in this request to the correct route, our server then returns an HTTP Response back to the client. Like our requests, this response is also formatted following special HTTP protocol. It consists of three primary elements:
The first line of a response message is a status code and reason phrase. (An example is 200 OK
, which is shown in the picture above.) The HTTP status code is a three-digit number that indicates how the request was processed (or not). Each is accompanied by a brief, human-readable description.
Below is a list of the five status code classes determined by the first digit of the code, and their most common codes. You don't have to memorize these; simply get an idea of what's out there, and refer back as necessary. (And, to see a complete list, visit HTTP Status Codes.)
1
indicate the request was received. This class of code is rarely used.2
indicate the request was received and handled successfully. These are very common. For example:
3
indicate that additional action is required to complete processing the request. For example:
4
indicate that something was wrong about the request. Some of the most common include:
5
indicate that something went wrong on the server side, such as a bug in the code or a server that went down. For example:
Like request headers, response headers include additional protocol providing more details about the HTTP response. Some examples of response header fields include:
For a list of all possible response headers, see here.
The response body includes all of the content for the resource requested. It's often referred to as the payload. When we issue a GET request for the /items/new
path of our to do list, we expect the body to include an HTML document with the form we created to make new Item
s.
The last line of code in a controller route indicates the resource that should be returned in the body of the response. In the case of our application, the resource is a view.
When the browser receives the response from the server, it then renders the HTML into a viewable format for the user. The whole process begins again as the user actions trigger additional requests for the server to manage.
Follow the link below to view how a sample version of the project should look at this point. Note that this is a link to a specific commit in the repository.
HTTP Method: The kind of action that the client is requesting to be done in the web server, also known as a verb. Most frequently used HTTP methods: GET
and POST
.
GET: A request method that retrieves information from the server but does not change anything on the server. Example: request to see a homepage for a site.
POST: A request method that acts upon the resource by adding, updating or deleting information on the server. Example: submitting a form to join a mailing list which adds your name to the list.
HTTP Request Header: The first lines of an HTTP request message that include information about the client, server and the request. Common headers include Host, User-agent, and Accept-language.
HTTP Request Body: Data that needs to be transmitted to the server in the HTTP request message (like data from a submitted form).
Status code: First line of the response message from the server consisting of a three-digit number indicating the status of the request. Example: 200 indicates that the request was successfully processed.
Status reason: The human language interpretation of the status code, not read by the client but intended for humans.
Payload: The data that was requested in the original request message that is not protocol. Example: the payload for a request for the main page of a website would be the actual HTML document content.
Complete List of HTTP Status Codes may be found here.
1xx Informational
2xx Success
3xx Redirection
4xx Client errors
5xx Server errors
Lesson 23 of 38
Last updated more than 3 months ago.