DPS907 notes – Tue Oct 11

Various topics, that will enhance and/or fill in foundation knowledge that has been covered in the past five weeks.

 

Test today

The weekly test will be done at the beginning of the class timeslot at 11:40am.

It is possible that the test will reach back a week or two, by asking questions from Weeks 4 and 5, in addition to this Week 6. So, make sure that you review that content.

 

Code examples

In the GitHub code example repository for this week, you will see several interesting assets.

Also, make sure that you get the updated project template, described next.

 

Updated project template, v2

In the past several weeks, we have learned how to add features to our web services. These features have been added to a new “version 2” project template, which is in the GitHub code repository. The new project template has:

  • Media type formatter for byte-oriented content
  • HTTP OPTIONS handler
  • Hypermedia-aware link relations generator
  • Root controller to handle requests to /api
  • Web API Help Page configuration
  • Minor improvement for exceptions/errors

 

Copy the zip file to the following folder. Do NOT un-zip the file. Leave it as-is:

%userprofile%\Documents\Visual Studio 2015\Templates\ProjectTemplates\Visual C#\Web

 

Minor improvement for exceptions/errors

Up to this point in the course, we have been using HTTP status codes and the ASP.NET Web API framework stack trace to communicate error conditions to requestors.

Today, we’ll make a minor improvement to that process. We take advantage of your recent experience in creating modules (byte formatter, HTTP OPTIONS handler) that plug into the request-processing pipeline.

In the near future, we will make another improvement to the process, by capturing and saving information about the error/exception.

 

Studying the changes

Open the BetterErrorHandling code example.

Notice the new class in the ServiceLayer folder. It is initialized in the Register method of the WebApiConfig class.

We have included a throw-away controller, CreateErrorController, that you can use to create (generate/cause) different kinds of errors. Use Fiddler to test your interaction with the controller.

 

Nested object(s), and link relations – how to render

Consider this scenario: We have a web service that is using the Chinook sample database. We want to render a collection of Artist objects. Do we render the Albums collection for each artist? Typically not, unless the use case calls for it.

However, for one specific Artist, do we render its Albums collection? Yes, we typically do that.

How does the recently-learned link relations topic affect this? Do we render links for only the enclosing/hosting Artist object? Or for all objects?

There’s no clear yes-or-no answer to these questions. In the HypermediaObjectGraph code example, we look at both kinds of answers.

Before studying and discussing the code, look at the two different kinds of “artist with albums” representations that we could create. Click to open the image full-size in its own tab/window.

nested-with-link-relations

 

Result 1 – render links only for the enclosing/hosting object

This is shown in the left side of the image above. Here’s how to make it work:

Resource models for both Artist and Album do declare/include the link relations classes (whether they get used or not). ArtistWithLink inherits from ArtistWithAlbums.

ArtistWithAlbums resource model has a collection property of AlbumBase objects.

The Manager “artist get by identifier” method returns an object graph, with album objects.

The controller method calls the Manager method. The return result is transformed into an ArtistLinked object, which has link relations generated for the Artist object. It is returned to the user/requestor.

 

Result 2 – render links for all objects

This is shown in the right side of the image above.

Resource models for both Artist and Album do declare/include the link relations classes (whether they get used or not). ArtistWithLink inherits from ArtistWithAlbums.

ArtistWithAlbums resource model has a collection property of AlbumWithLink objects.

The Manager “artist get by identifier” method returns an object graph, with album objects.

The controller method calls the Manager method. The return result is transformed into an ArtistLinked object, which has link relations generated for the Artist object.

At this point, the link relations factory, as noted above, has generated link relations for the enclosing/hosting Artist object. However, it did not generate link relations for the nested collection of albums. We must do that ourself. Therefore, in the controller, go through (“foreach”) the album collection, and manually add/generate a link relation for each Album object.

Then, return the result to the user/requestor.

 

Customizing the response, by hand-coding custom or special link relations

The code discussed in the previous section – manually adding/generating link relations – should suggest to you that you can do that for any object, before returning it to the user/requestor.

Every object or collection has a “Links” collection. As you know, the link factory for an object creates link relations for “self” and the parent “collection”. The link factory for a collection creates one link relation, for “self”.

You can add to this collection. For example, think back to the MediaUpload and Assignment5 work. One of the use cases was to get one book or instrument. The link relations for the commands – “set photo”, or “set sound clip” – were not automatically generated by the link factory.

No problem.

Create a new Link object yourself, configure it, and add it to the “Links” collection, before returning the result.

 

Mixing web app (MVC) and web service (Web API) controllers
in the same project

Can you have web app (MVC) and web service (Web API) controllers in the same project? Yes.

What about resource URIs – can we have this, for the Employee entity, for example:

  • Web app – /employees, or /employees/detail/5
  • Web service – /api/employees, or /api/employees/5

Yes.

It requires a bit of extra work, however.

 

What could go wrong

Assume that you have an existing Web API controller for the Employee entity. Its source code file will be named EmployeesController, and the class inside the file will also be named EmployeesController. This you know.

Now, assume that you want to add a web app (MVC) controller. If you attempt to add another controller with the same name, it will not be possible. Your first reaction may be to choose a new name, but that will affect the resource URIs for the web app. If you choose an ugly name (e.g. Employees2Controller, or EmployeesMVCController), then it’s bad news.

 

How to solve 

We suggest that you make small modifications to the web service (Web API) controller. Doing this will clear the way for you to add a web app (MVC) controller. Here’s the suggested sequence, using the Employee entity as an example.

1. Create a Web API controller, named EmployeesController.

2. In Solution Explorer, rename the new source code file to EmployeesApiController. When asked “Would you also like to perform a rename…?”, answer No.

3. Change the namespace name to <projectname>.Controllers.Api.

4. Then, you can create an MVC controller, also named EmployeesController.

 

This all works because we are placing the Web API controller in a different namespace. That enables us to support two classes named EmployeesController, because they will be in different namespaces.

 

Creating HTML5 apps (requestors) that can use the web service

The SimpleHtml5App code example includes two pages – list of artists, and artist detail – that are HTML5 clients.

How can you use them?

First, load/run/execute the HypermediaObjectGraph code example on your computer. It needs to be running in the on-demand web server.

Next, load the “artists.html” file in a browser. Its JavaScript will call out to the web service, and render the data. Click the image to view it full-size in a new browser tab/window.

html5app-artist-list

 

If you select one of the “Details” links, it will load “artistdetail.html” with a query string argument that has the identifier of the artist. Its JavaScript will call out to the web service, and render the data. Click the image to view it full-size in a new browser tab/window.

html5app-artist-detail

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Advertisements
%d bloggers like this: