• No results found

Dealing with single items

Our updated ItemsController class has everything we need to build our Welcome View:

as soon as we learn how to call it from our client code, we'll be able to fetch the required data to populate all the item lists we expect to have within our GUI.

However, we don't have anything yet to handle any kind of user interaction. When our users click an item, they will surely expect to read something more about it; ideally, they will want to see something similar to a detail page.

To put it in other words: since our Welcome View features a list of clickable items, sooner or later we'll have to give our users the chance to select one of them, ideally with a left mouse click and display the selected item's details: something like a master/detail navigation pattern of any sort.

We're not dealing with the client-side code yet, so we don't know how we'll present such a scenario to the user. However, we already know what we'll eventually need: an API call to retrieve a single Item by passing its unique Id. To do that we need to provide our

controller with the appropriate API method, which could be something like this:

/api/items/Get/{id}

This means that we need to add something more to our ItemsController source code.

While we're at it, let's take the chance to make some more improvements:

A sample method based upon the standard RESTful conventions, just to demonstrate how we can handle that

A parameterless overload for each method, to make their usage easier A couple more private properties to define:

The default number of items to retrieve using the parameterless overload

The maximum number of items to retrieve within a single API call The resulting code can be seen as follows (new lines are highlighted):

using System;

public class ItemsController : Controller {

#region RESTful Conventions /// <summary>

/// GET: api/items /// </summary>

/// <returns>Nothing: this method will raise a HttpNotFound HTTP exception, since we're not supporting this API call.</returns>

[HttpGet()]

public IActionResult Get()

/// <returns>A Json-serialized object representing a single item.

</returns>

/// <returns>An array of {n} Json-serialized objects representing the last inserted items.</returns>

/// GET: api/items/GetMostViewed /// ROUTING TYPE: attribute-based /// </summary>

/// <returns>An array of a default number of Json-serialized objects representing the items with most user views.</returns>

[HttpGet("GetMostViewed")]

/// <returns>An array of {n} Json-serialized objects representing the items with most user views.</returns>

[HttpGet("GetMostViewed/{n}")]

public IActionResult GetMostViewed(int n) {

Json-serialized objects representing some randomly-picked items.

</returns>

/// <returns>An array of {n} Json-serialized objects representing some randomly-picked items.</returns>

[HttpGet("GetRandom/{n}")]

public IActionResult GetRandom(int n) {

if (n > MaxNumberOfItems) n = MaxNumberOfItems;

/// <param name="num">The number of items to generate: default is 999</param>

/// <returns>a defined number of mock items (for testing purpose only)</returns>

private List<ItemViewModel> GetSampleItems(int num = 999) { description for item {0}: Lorem ipsum dolor sit amet.", id), CreatedDate = date,

/// Returns a suitable JsonSerializerSettings object that can be used to generate the JsonResult return value for this Controller's methods.

/// </summary>

private JsonSerializerSettings DefaultJsonSettings {

get {

return new JsonSerializerSettings() {

};

} }

/// <summary>

/// Returns the default number of items to retrieve when using the parameterless overloads of the API methods retrieving item lists.

/// </summary>

We've already explained the new goodies out there, yet it can be useful to focus on a couple of them:

Our brand new Get() method won't do anything more than return a 404 HTTP Error with a custom error string. We added it to grant an explicit response to that RESTful default call and also to demonstrate how we can choose between handling them or not.

The DefaultNumberOfItems and MaxNumberOfItems have been added to store their values in a centralized way, so we can avoid repeating them multiple times.

We made them as properties, but they could also be defined as constants or private variables as well since they are meant to be for internal use only; we won't reference them outside this class or anywhere else.

Let's test our new methods: select Debug | Start Debugging from the main menu (or hit F5) and type the following URLs in the browser's address bar:

/api/items

/api/items/5

As we've already said, the 404 Page Not Found error in response to the first HTTP request is perfectly fine; we did it on purpose to demonstrate how we can handle these kinds of errors. This is also good practice when dealing with ASP.NET Core API interfaces; since we chose to not accept any /api/items get call without parameters, we want the client to be aware of that.

So far, so good; we've got ourselves a number of server-side APIs to retrieve JSON arrays filled by a client-defined (or default) number of latest items, and an additional one to retrieve a single item from its unique ID. All of these calls will be very handy in the following chapter, where we'll start developing client-side components using Angular 2.

Suggested topics

HTTP request, HTTP response, convention-based routing, attribute-based routing, RESTful conventions, mock objects, test-driven development, XML documentation tags, and C#

preprocessor directives.

Summary

We spent some time putting the standard application data flow under our lens: a two-way communication pattern between the server and their clients, built upon the HTTP protocol.

We acknowledged the fact that we'll be mostly dealing with JSON-serializable object such as Items, so we chose to equip ourselves with an ItemViewModel server-side class,

together with an ItemsController that will actively use it to expose the data to the client.

We started building our MVC6-based Web API interface by implementing a number of methods required to create the client-side UI we chose for our Welcome View, consisting of three item listings to show to our users: last inserted ones, most viewed ones, and some random picks. We routed the requests to them by using a custom set of attribute-based routing rules, which seemed to be the best choice for our specific scenario.

While we were there, we also took the chance to add a dedicated method to retrieve a single Item from its unique Id, assuming that we were going to need it for sure.

In the next chapter, we will see how we can consume the ASP.NET Core Web API using Angular 2 in order to build an interactive user interface for our application.

Angular 2 Components and 3

Related documents