We already said that action methods return IAsyncResult implementations, which are then executed by the framework after possible action filters have been applied. This lesson classifies all predefined IAsyncResult implementations and gives more details about each of them.

ViewResult and View method

The ViewResult implementation is returned when an action method calls the View method when we write return View(...);. The View method has several overloads. Each overload can specify whether or not which of the paths of the view to invoke and which ViewModel to pass it. If no view name is specified the framework tries to find a view with the same name of the action method, while if no ViewModel is specified a null ViewModel is passed to the view.

In order to retrieve a view, the View method adds the .cshtml extension to the view name it receives and then interprets it as paths. If the path is relative the view is first searched in a folder with the same name of the controller. For instance, Home for the HomeController, which is under the Views folder. If the view is not found there it is searched under the “Shared” folder, which is always under the Views folder. Absolute paths that start with a / are not searched in the hard disk root, but in the application root folder.

When a view is invoked it is passed the current request HttpContext, the controller TempData, and the Controller ViewData, plus the whole controller ModelState that is used to show all errors computed so far, in the view.

We already used the View method in several examples, so you should already know everything was said in this section.

PartialViewResult and PartialView method

We never used the PartialViewResult and the PartialView method, but they are completely analogous to ViewResult and View. They invoke a view with exactly the same procedure we described in the previous section, but the view they invoke is not inserted inside any layout view.

This is because their purpose is not to render a whole HTML page but just an HTML fragment to be returned to an AJAX call. Sometimes, instead of completely changing a page, it is convenient to modify an area of the current page. This can be achieved by invoking an action method that returns the HTML that must replace a part of the page via JavaScript. Then, the same JavaScript snippet that invoked the action method can perform all needed DOM manipulation to update the target page area with the newly received HTML.

Dynamic modification of the Web page HTML enables the user to continue their interaction with the page while the new HTML is being loaded.

AJAX calls that return HTML have lost their popularity since modern client-side JavaScript frameworks like REACT, Angular, and Vue.js can create new HTML without the help of the server. At the moment, the most common way to dynamically update page areas is to retrieve JSON data from API controllers and to use these client-side frameworks to render the retrieved data with fresh HTML fragments.

We will see some examples of usage of PartialView in the chapter dedicated to HTML code reusability.

RedirectResult and Redirect

The Redirect method accepts a URL and returns a redirect response to the browser. When the browser receives this response it issues a new GET request to that URL. It is used mainly to move the browser to a different website because the best way to move the browser to a URL on the same website is the usage of RedirectToAction.

RedirectToActionResult and RedirectToAction

Similar to Redirect, RedirectToAction returns a redirect response to the browser, but this time the URL is computed through the name of the target action name, controller, and route data.

This way, if the routing rules are changed there is no need to change the code. If the controller argument is omitted the current controller is taken to compute the URL. All route and query string parameters are passed through an anonymous object as shown below:

return RedirectToAction("MyActionMethod", "MyController", new {id=3, culture="it"});

We already used RedirectToActionResult in various examples. If you need to refresh your knowledge, please review the second lesson of this chapter.

The Content and File methods

The Content method returns a text result and gives us the opportunity to define its content-type. We described the Content method in the second to last lesson, please review it, if you don’t remember how to use it.

The File method instead returns generic binary data and gives us the opportunity to define their content-type. We described the File method in the previous lesson, please review it, if you don’t remember how to use it.

The Unauthorized and Forbidden methods

The Unauthorized method returns a 401 code, meaning login is required and the user is not logged in. If there is an authorization logic in place, this result might cause a redirect to the login URL. We will analyze authorization logic in detail in a dedicated chapter. Forbidden returns a 403 code meaning the user is logged in but does not have enough privileges to access the URL.

We should never call these methods as they are called automatically by the [Authorize] action filter that handles authorization logic, which we will describe in a dedicated chapter.

The Json method

The Json method formats the objects passed as argument in JSON and adds it to the response. It has a second optional argument that may contain the options to pass to the .NET JsonSerializer instance that carries out the serialization. This should only be used if we need to customize the way JSON must be produced with the options argument, otherwise, it is better to prefer the API controller-specific methods described in the next section.

StatusCode and API controllers

StatusCode is used mainly by API controllers that accept and return JSON or XML. It allows specifying both the status code and the object to be converted in JSON and XML. StatusCode has shortcuts for specific status codes. The table below summarizes and suggests when to use each of them:

Method What it does When to use it
Created(string uri, object o) Returns a 201 code, with an object containing the URI of a new resource, and the newly created resource After a successful POST that created a new resource.
OK(object o = null) Returns a 200 code with an optional object After the successful completion of any operation different from creation.
Accepted(sting URI, object o) Returns a 202 code with an optional object containing an optional URI and an optional object representing a resource Whenever an operation is accepted but not executed. The URI is the location of the updated or created resource.
NoContent() Returns a 204 code with an empty body Whenever an operation is successfully executed but there is no information to return.
NotFound(object o=null) Returns a 404 code and an optional object with further information on the error Whenever a resource required by the client is not found.
BadRequest(ModelState errors) Returns a 400 code and the list of all errors contained in the ModelState Whenever the client sends an ill-formatted request.

Both Accepted and Created have analogous AcceptedAtAction and CreatedAtAction methods that compute the URI contained in the response through action method name, controller name, and route parameters.

Get hands-on with 1400+ tech skills courses.