DPS907 notes – Thu Oct 15

Request-processing pipeline. Adding a “handler” to the pipeline. Project templates. Document your API.

 

Review Test 4

Test 4 will be returned and discussed. The goal is to help you improve your answer quality.

Example answers will be posted after each test. On the class notes page, click any of the test links, to view the answer page.

 

Test 5 is today

Next, Test 5 will be written.

 

Q&A session about Lab 5

Be prepared to ask questions about Lab 5, which is due next Monday, October 19.

 

Message lifecycle (aka “request-processing pipeline”)

You are probably aware that a request message flows through a request-processing pipeline before a response is returned to the requestor.

It’s time to learn more about the message lifecycle, so that you can modify or affect a message as it flows through the pipeline. In later sections, you will learn how to handle exceptions, and the HTTP OPTIONS method. Both tasks require you to create code that “plugs in” to the pipeline.

Later in the course, you will continue to create more extensibility points.

The image below shows the message lifecycle. Click to open a PDF full-size in its own tab/window.

aspnet-web-api-poster

 

Flow from the request to the controller action

The following is a brief summary of the flow:

  1. Web server host handles the request, and creates an HttpRequestMessage object
  2. Routing dispatcher module activated for a Web API (or MVC) request
  3. Controller dispatcher selects controller, then the action (method)
  4. If applicable, authentication happens
  5. If applicable, authorization happens
  6. Model binding happens, for data in the URI, headers, and entity body
  7. Controller action (method) is invoked, with the data

 

Flow from the controller action to the response

The following is a brief summary of the flow:

  1. The result of the controller action (method) is converted to an HttpResponseMessage
  2. If the result was an error, the built-in error handler is invoked
  3. Web server returns the HTTP response to the requestor

 

Handling errors elegantly

Up to this point in the course, we have been using HTTP status codes to communicate success and error conditions to requestors.

In this section, you will learn how to add a module that will enhance this functionality, by handling errors more elegantly. It will also save detailed information about the error.

Open and study the ErrorHandling code example.

As described in the previous section, the result of a controller action (method) may be an error, which involkes the built-in error handler. That module does not do enough for us. For example, it will not help us with an “internal server error” in an Azure-deployed web service.

 

Implementing an error-handling module

DesignModelClassesThe first step in this process is to create a design model class for the error. In the ErrorHandling code example, there is a new class named ExceptionInfo.

It has properties that enable us to record important information about the error.

Next, configure the new entity in the infrastructure.

Add a DbSet<TEntity> property to the data context class.

Add some resource model classes. “Base” and “add” would probably be enough, because we need to view and add only.

Next, in the ServiceLayer folder, create a new class source code file, perhaps named HandleError.cs. This source code file will hold two classes:

  • HandleError, inherits from ExceptionHandler
  • LogError, inherits from ExceptionLogger

HandleError will create an error information object, and return it to the requestor.

LogError will save a detailed error information object to the persistent store.

After writing the code for the modules, they must be added to the app’s configuration. This is done in the WebApiConfig class (the source code is in the App_Start folder).

You do not have to change any of your controller or repository code. It is plug-and-play. It just works.

 

How can we view the errors?

Well, think about it: We just created the code necessary to save error information in the persistent store.

How do you get anything out of the persistent store? Write a controller!

The ErrorHandling code example includes an “exceptions” controller, which enables you to view all errors, or one error at a time.

You may also notice a “create error” controller. Yes, it enables you to create errors on demand. You do not need this controller in a shipping app, but it is useful for testing purposes.

 

The official ASP.NET documentation for this global error handling approach is on this page:

Global error Handling in ASP.NET Web API 2, by Rick Anderson and David Matson

 

Handling an HTTP OPTIONS request

A hypermedia-driven design must support the HTTP OPTIONS method.

From RFC 7231:

The OPTIONS method requests information about the communication options available for the target resource…  This method allows a client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action.

 

This enables a requestor to determine what HTTP methods are supported by a URI, before sending the actual request.

Instead of using GET with a request URI, use OPTIONS with a request URI.

The response will include a response header named “Allow”, with a comma-separated list of HTTP method names that can be used with the URI. It’s as simple as that. (The entity body is empty.)

Does the Web API project automatically handle OPTIONS requests? No. We must write code to do this.

Do we need to write code in every controller? That would be annoying. No, we don’t.

The recommended approach is to create a “handler”, which will intercept and process any request that uses the OPTIONS method. The request is serviced by a single module, and it returns a useful response to the requestor. This is a better alternative to writing code in every controller.

Your professor acknowledges the post by Jef Claes that enabled the handler to get written. Then, Yao Huang Lin’s post provided the knowledge that resulted in it covering all kinds of URIs.

 

Implementing an HTTP OPTIONS handler

Instead of writing this handler from scratch, students in Prof. McIntyre’s Web Services course have permission to use the code that’s found in the HttpOptionsHandler code example folder. (The folder does not include a complete project – just the source code file that you need.)

Just copy the HandleHttpOptions.cs source code file into any existing project, change its namespace name to match your project, add it to the Register method body in the WebApiConfig class, and it will just work.

You’re welcome.

Study the code, to learn how it works.

 

Refactor the link relations classes

After studying the HTTP OPTIONS handler code, you probably noticed that there is an API Explorer class.

ResourceModelLinkIt is a wonderful piece of code, written by a team led by Yao Huang Lin (called out above; read his introduction to ApiExplorere here). It enables a programmer to get information about the structure of a Web API app.

Remember the Link class? (Yes, obviously you do.)

It has a “Method” property. It would be really nice to use the API Explorer to get the allowed HTTP methods for the link URI, and use that in the Method property.

Well, let’s do it. Your professor has created a new version of the Links_vm.cs source code file, and placed it alongside the HTTP OPTIONS handler module, in the HttpOptionsHandler code example.

Just copy the Links_vm.cs source code file into any existing project, replacing the existing source code file. Remember to change its namespace name to match your project.

You’re welcome.

 

Documentation for your web service

Link relations and the enhanced links resource model classes have improved our ability to describe our web service to requestors.

It may not be enough, however.

When you run your app, it loads in a browser. You may have noticed an “API” link on the top-of-page menu strip.

docs-built-in

 

The link will show you pages that are generated by the Web API Help Page feature. This feature is turned on, but not fully configured, in every new Web API project in Visual Studio 2013 Update 3 and later. (Its principal author is again, Yao Huang Lin. A busy guy.)

Its default configuration will show a list of all the requests that can be handled by your app’s controllers. It does this by looking for classes that inherit from ApiController, and then inspecting their methods and routes. The ApiExplorer class enables this feature.

In its default configuration, every documented request has a “Description” field that reads “No documentation available”. We should change that, to make the documentation more useful:

docs-built-in-configured

 

Implementing the Web API Help Page

There are several discrete tasks to fully implement a useful Web API Help Page.

 

Change the project’s properties

Open the project properties panel, and show the Build settings.

In the “Errors and warnings” settings, add “CS1591” to the “Suppress warnings” textbox. As it suggests, it will suppress warnings for C# compiler warning number 1591.

In the “Output” settings, check (mark) the “XML documentation file” setting, and add a file path name (App_Data\XmlDocument.xml) to the textbox. As it suggests, the compiler will output/save the data to that named file.

Save, and close the project properties panel.

docs-properties-build

 

Configure the help page to use the just-configured XML documentation file

Open the source code file that holds the HelpPageConfig class. It’s in Areas > HelpPage > App_Start.

Uncomment the statement that sets/configures the XML documentation file:

docs-config-class

 

Add documentation to controller methods

For each public web service controller method, add XML Documentation Comments.

If you have never used this feature, here’s how to get started: Position the cursor on the line above the method declaration statement. Type a triple slash ( / / / ). That will add the structure. Then, fill it in with useful comments.

Incidentally, you can add XML Documentation Comments to every method and property, in every class, in your project. Then, during coding, Visual Studio will use the data as you write code, and show it with its code sense feature. (Yes, this is how Microsoft has done this for framework-provided code.)

docs-xml-comments

 

When you build and run your project, the compiler will generate the content it needs to fully configure the Web API Help Page feature.

Please follow the instructions above. They are intended for late 2015 projects. However, you should also read/skim the original documents that describe the Web API Help Page feature, because they include some background information and so on. Be careful, because some of the documents are two or three years old, and may not (or will not) apply to current new projects.

Creating Help Pages for ASP.NET Web API, by Mike Wasson, April 2013

Introducing the ASP.NET Web API Help Page, by Yao Huang Lin, August 2012

More info, Part 1, Part 2, and Part 3, by Yao, also from 2012

 

 

Configure an initial URI for the web service

docs-initial-uriA hypermedia-driven design also needs an “initial URI“.

The idea is that the web service provider can publish one single URI for the web service, and clients/requestors will be able to use that to discover all of the available resources.

To do this, we must perform these steps:

  1. Add a default value for the “controller” placeholder, in the App_Start > WebApiConfig class
  2. Add a new ApiController class that uses the value you provided above
  3. Implement a single ‘get’ method, which returns a collection of link relations

 

The familar LinkRelationsMore code example was enhanced with this feature, and posted in this week’s folder on the GitHub repository.

 

Programming improvement techniques

We are more than one-third of the way through the course. You have had several weeks experience with web service programming.

Are you working efficiently? With an appropriate level of effort?

When you create a brand-new project, do you like the coding experience, and the effort needed to run the app and work with it in Fiddler? How much time and effort does that take?

Ten minutes?

Thirty minutes?

Sixty minutes?

It’s probably about thirty minutes, if you know what you’re doing, and are good at it. Is that a reasonable time to spend?

Would you like to eliminate that time and effort? How? With a Visual Studio project template.

.

Visual Studio project templates

As you know, Visual Studio includes a number of project templates. You have used templates to create new web apps, and new web services.

And, you can create your own templates. How?

Briefly, create and configure a project with all the code assets needed. For example, a design model, repository classes, updated packages, AutoMapper, and so on. Then, save your work as a template.

Next time you wish to create a new project, its template will be available for selection.

.

Suggestions for creating a template

One of the challenges in creating a template is to ensure that it has enough code to be useful to build upon. To be really useful, it should have a design model, an entity-specific repository, some resource models, and a controller. In other words, it should be a completely working web service.

But how do we do so, without the need to remove code in the future, after you have added your own entity classes in the design model, and all the other code? Well, the simple answer is that we ensure that the code does not have to be removed, and remains useful.

Above, you learned how to handle exceptions in a way that enables you to inspect the details of the exception. Therefore, the template should include this functionality. It requires a design model, a repository, some resource model classes, and a controller. So, this is an ideal solution.

In the coming weeks, as you learn more functionality, you can add each one to the template, using this procedure:

  1. Create a new project, based on the most recent project template
  2. Add (code) the new functionality
  3. Save this work as a new project template, to replace the previous one

 

In the Week 6 folder on the GitHub code example repository, you will notice a zip file. This is a project template that was created with all the functionality covered up to now in this course. Copy it to this folder (pay attention to the Visual Studio 2013 or 2015 part of the path, and edit if necessary):

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

 

Read more about creating a project template in this document:

Custom Visual Studio 2015 project templates

 

Read more about creating a project template in the following MSDN document:

Creating Custom Project and Item Templates in Visual Studio

.

.

.

.

.

.

.

.

.

.

.

.

.

.

%d bloggers like this: