• No results found

103MVC Controllers and action methods

Creating web pages with MVC Controllers

103MVC Controllers and action methods

Based on these requirements, it’s possible to come up with a variety of naming con- ventions and hierarchies for your controllers, all of which will be discovered and found at runtime. In general, though, it’s far better to stick to the common conven- tion of naming your controllers by ending them with “Controller”, and optionally inheriting from the Controller base class, as shown in the following listing.

public class HomeController: Controller

Suffix your controller names with “Controller” {

public ViewResult Index() {

return View();

Inheriting from the Controller base class allows access to utility methods like View()

} }

public class ValuesController

If not using the utility methods in your controller, you don’t need to inherit from Controller {

public string Get() {

return "Hello world!"; }

}

It’s worth noting that although these examples have (implicit) parameterless con- structors, it’s perfectly acceptable to have dependencies in your constructor. In fact, this is one of the preferred mechanisms of accessing other classes and services from your controllers. By requiring them to be passed during construction of the control- ler, you explicitly define the dependencies of your controller, which, among other things, makes testing easier. The dependency injection container automatically popu- lates any required dependencies when the controller’s created.

NOTE See chapter gten for details about configuring and using dependency injection.

The controllers you’ve seen this far contain a single action method, which is invoked when handling a request. In the next section, I’ll look at action methods, how to define them, how to invoke them, and how to use them to return views.

4.2

MVC Controllers and action methods

In the first section of this chapter I described the MVC design pattern and how it relates to ASP.NET Core. In the design pattern, the controller receives a request and is the entry point for the UI generation. In ASP.NET Core, the entry point’s an action method that resides in a controller. An action, or action method, is a method that runs in response to a request.

MVC controllers can contain any number of action methods. Controllers provide a mechanism to logically group actions together and apply a common set of rules to

them. For example, it’s simple to require a user to be logged in when accessing any action method on a given controller by applying an attribute to the controller; you don’t need to apply the attribute to every individual action method.

NOTE You’ll see how to apply authorization requirements to your actions and controllers in chapter fourteen.

Any public method on a controller acts as an action method, and can be invoked by a client (assuming the routing configuration allows for it). The responsibility of an action method’s generally threefold:

1 Confirm the incoming request’s valid.

2 Invoke the appropriate business logic corresponding to the incoming request. 3 Choose the appropriate kind of response to return.

An action doesn’t need to perform every one of these actions, but it must choose the kind of response to return. For a traditional MVC application returning HTML to a browser, action methods typically return either a ViewResult that the MvcMiddleware uses to generate an HTML response, or a RedirectResult, which indicates the user should be redirected to a different page in your application. In Web API applications, action methods often return a variety of different results, as you’ll see in chapter nine.

It’s important to realize that an action method doesn’t generate a response directly; it selects the type of response and prepares the data. For example, returning a ViewResult doesn’t generate any HTML, it indicates which view template to use and the view model it has access to. This is in keeping with the MVC design pattern in which it’s the view that generates the response, not the controller.

TIP The action method’s responsible for choosing what sort of response to send; the view engine in the MvcMiddleware uses the action result to generate the response.

It’s also worth bearing in mind that action methods should generally not be per- forming business logic directly. Instead, they should call appropriate services in the application model to handle requests. For example, if an action method receives a request to add a product to a user’s cart, it shouldn’t directly manipulate the database or recalculate cart totals. Instead, it should make a call to another class to handle the details. This approach of separating concerns ensures that your code stays testable and manageable as it grows.

4.2.1 Accepting parameters to action methods

Some requests made to action methods require additional values with details about the request. For example, if the request’s for a search page, the request might contain details of the search term and the page number they’re looking at. If the request’s post- ing a form to your application, for example a user logging in with their username and password, then those values must be contained in the request. In other cases, there’ll

105