• No results found

105MVC Controllers and action methods

Creating web pages with MVC Controllers

105MVC Controllers and action methods

The request may contain additional values from a variety of different sources. They could be part of the URL, the query string, headers, or in the body of the request itself. The middleware extracts values from each of these sources, and converts them into .NET types.

If an action method definition has method arguments, the additional values in the request are used to create the required parameters. If the action has no arguments, then the additional values goes unused. The method arguments can be simple types, such as strings and integers, or they can be a complex type, as shown in the following listing.

public class HomeController: Controller {

private SearchService _searchService; The SearchService is provided to the HomeController for use in action methods public HomeController(SearchService searchService)

{ _searchService = searchService; }

public ViewResult Index() An action without parameters requires no additional values in the request {

return View(); The method doesn’t need to check if the model’s valid, it only returns a response. }

public IActionResult Search(SearchModel searchModel)

The action method requires the request to have values for the properties in SearchModel {

if(ModelState.IsValid) If the model’s valid, a view model’s created and passed to the view {

var viewModel = _searchService.Search(searchModel); return View(viewModel); }

return Redirect("/")

If the model isn’t valid, the method indicates the user should be redirected to the path “/” }

}

In this example, the Index action method doesn’t require any parameters, and the method’s simple—it returns a view to the user. The Search action method, on the other hand, accepts a SearchModel object. This could contain multiple different prop- erties that are obtained from the request and are set on the model in a process called

model binding. The SearchModel object’s often described as a binding model.

NOTE I’ll discuss model binding in detail in chapter six.

When an action method accepts parameters, it should always check that the model provided’s valid using ModelState.IsValid. The ModelState property’s exposed when you inherit from the base Controller class, and can be used to check the

method parameters are valid. You’ll see how the process works in chapter six when you learn about validation.

Once an action establishes that the method parameters provided to an action are valid, it can execute the appropriate business logic and handle the request. In the case of the Search action, this involves calling the provided SearchService, to obtain a view model. This view model’s returned in a ViewResult by calling the base method

return View(viewModel);

If the model wasn’t valid, then we don’t have any results to display! In this exam- ple, the action returns a RedirectResult using the Redirect helper method. When executed, this result sends a 302 redirect response to the user, which causes their browser to navigate to the home page.

Note that the Index method returns a ViewResult in the method signature, but the Search method returns an IActionResult. This is required in the Search method to allow the C# to compile (as the View and Redirect helper methods return different types of values), but it doesn’t change the final behavior of the methods. You could’ve returned an IActionResult in the Index method and the behavior would be identical.

TIP If you’re returning more than one type of result from an action method, you’ll need to ensure your method returns an IActionResult.

4.2.2 Using ActionResults

In the previous section I emphasized that action methods only decide what to gener- ate, and don’t perform the actual generation of the response. It’s the IActionResult returned by an action method which, when executed by the MvcMiddleware, gener- ates the response. The MvcMiddleware uses the view engine to execute.

This approach is key to following the MVC design pattern. It separates the decision of what sort of response to send from the actual generation of the response. This allows you to test your action method logic to confirm the right sort of response is sent for a given output. You can separately test that a given IActionResult generates the expected HTML.

Many different types of IActionResult exist in ASP.NET Core, such as:  ViewResult—Generates an HTML view.

 RedirectResult—Sends a 302 HTTP redirect response to automatically send a user to a specified URL.

 RedirectToRouteResult—Sends a 302 HTTP redirect response to automati- cally send a user to another page, where the URL is defined using routing.  FileResult—Returns a file as the response.

 ContentResult—Returns a provided string as the response.

 StatusCodeResult—Sends a raw HTTP status code as the response, optionally with associated response body content.

 NotFoundResult—Sends a raw 404 HTTP status code as the response.

107