DPS907 notes – Thu Sep 17

Test (quiz) today

The course’s tests begin today. (You can also think of them as quizzes.)

Tests are written. Pen or pencil. Answer styles will vary, but we’re mostly looking for short- to medium-length answers, and/or diagrams, and so on.

No references or resources are permitted – “closed book, open brain”.

We’ll do the test at the beginning of the time period, at 9:50am. Today’s test will run about 12 minutes. (Future tests will range in length from 10 to 20 minutes, with a grade value that tracks the length of the test.)

The tested topics are mostly forward-looking. You are tested on your comprehension, understanding, and application of the current week’s topics. For this week, it’s mostly the notes below, and the posted code example. Also, you may be tested on a recently-covered topic, which enables you to show that you have the foundational knowledge needed for current and future tasks.

.

Refresh your memory, ASP.NET MVC

If you have been away from ASP.NET MVC web app programming for a semester or more, and need a refresher, continue reading.

If you have never done ASP.NET MVC programming – because your ASP.NET training used the Web Forms technology – you have a different kind of problem. Continue reading below, in the next section.

Your professor teaches the web apps course in the Software Development degree program, BTI420. The class notes page has full coverage of all the topics, and the resources page will be useful.

Here are some recommended highlights (green-headed sections) from the class notes.

January 13, 2015

Introduction to ASP.NET

Writing code, writing classes

January 20

Object initializers

Collections

Data relations/associations

LINQ (language-integrated query)

January 22 & 26

The “data manager” concept

January 27

The role of a view model class

What about design model classes, which describe our real-world entities?

What is AutoMapper? What problem does it solve?

February 3

Working with your classes in an Entity Framework environment

AutoMapper and associated entities

.

The web app code examples are also available, on the BTI420 GitHub repository. You can use a browser to view the code, or you can download the entire collection of projects in a single zip file.

.

Did you complete your ASP.NET web apps course in 2012 or earlier?

If yes, then you learned the “web forms” version of ASP.NET.

This course uses the ASP.NET Web API framework, which is based on ASP.NET MVC. As someone who learned “web forms”, the “MVC” technology is very different. In fact, it’s different enough that your previous “web forms” knowledge is obsolete and not useful.

Is it possible to adapt? Yes. Should you stay in the course? Well, it is possible to pass. What happened last year? Six students were in this situation. Three stayed in the course and passed. One stayed and failed. Two dropped the course.

How can you get help? Read, study, and practice the resources above in the “Refresh…” section.

Is there any other help available? Maybe. Send me email. It may be possible to schedule an extra dedicated session to cover the topics that will help you transition your past experience to the new frameworks.

.

The MVC design pattern

Modern web apps and web services are often based on the MVC design pattern.

Controller code interacts with the user and therefore manages the app’s workflow

The important idea is that the controller is the most important role. User input is handled by the controller, which then works with the app’s data, and then prepares the view that’s returned to the user.

How does this map to a web service?

Model code does the same job as it does in a web app

View code – for an HTML page – is not present; instead, your controller methods return an object (or a collection), and the response is prepared by the default built-in serializers, or in custom code

Inside a Web API project

An ASP.NET MVC web app or web service uses the front controller pattern (Wikipedia overview article). Every request is inspected by a single module, and then dispatched to the code module that can handle the request.

The dispatch destination is defined by routes. By default, web service request URIs include an “/api/” segment, although we can change that default in the future. Then, by default, the next segment of the route designates the controller that will handle the request. The HTTP request method, along with the presence of a query string, and/or an entity body, will then determine the method in the controller that handles the request. Routing basics are covered in this ASP.NET Web API article. Study the other articles in the “Routing” collection of articles.

Data in-and-out of the web service is handled by serializers. By default, the Web API project template can handle three internet media types:

Which media type gets returned? It depends, on several factors. Read this ASP.NET Web API article on content negotiation (often abbreviated as “conneg”), and think about the different use cases.

.

System design guidance and how-to

During this course, you will learn to create a web service that has some level of sophistication. Therefore, you will need some guidance on how to design the system.

In your second-year web app programming and systems analysis courses, you used a “system design guidance” diagram to help you learn a set of topics. We will use a version of that diagram that’s customized for a web service. Click to open the PDF in a new tab/window:

Code examples for this semester

GitHub is a hosting service for source code. It offers a web interface to enable easy browsing. It also offers a set of tools and capabilities that enable software developers to publish code, collaborate with others, and improve their productivity and effectiveness.

On this web site, a link to the repository is on the right side of the page, near the top. (For best results, open the link in a new tab or window.)

Beginners can use a web browser to view the source code. You can also click the “Download ZIP” button to get a full and complete copy of all code examples in the repository.

For this course, the code examples will be published weekly, in logically-named folders (e.g. “Week_02”).

During the course’s lifetime, about twenty code examples will be published.

As you have observed, each ASP.NET web app or web service project includes a sizable “packages” folder. In the GitHub code repository, each distinct code example does not include the “packages” folder, as a time-saving measure. Each “packages” folder is about 50MB in size, so twenty code examples would require about 1GB storage. The contents of the “packages” folder does not compress much.

However, a single “packages” folder has been placed at the root of the repository. After you download-and-unzip the repository, simply copy-paste the “packages” folder into any distinct code example’s folder to make it ready for use and learning.

All code examples are designed to be usable and error-free. Each should compile and execute correctly.

If you have any problems with a code example, please contact your professor.

.

Assembling a web service project

For the next week or so, please use the following technique to create a web service project.

Make sure that you are using Visual Studio 2013, with update 3 or above (check HELP > About Microsoft Visual Studio for details)

After the project is created, use the NuGet package manager to update all packages, and then build/compile the project

.

What is in the project?

It includes a web app and a web service.

The project includes the familiar “home” controller, enabling a browser to open the root of the web app. It also includes a “help” controller that will dynamically build a human-readable documentation set for your web service.

The project includes a web service controller (named “ValuesController”).

It also includes a persistence stack, based on the Entity Framework, connected to a local file-system-based database instance that runs in an on-demand SQL Server engine.

Finally, it includes an authentication and authorization framework, based on the emerging web standards for these tasks, OAuth2 and OpenID Connect (and it also includes connectors to third-party services, such as Google and Facebook). Later in the course, we will begin to use the security framework.

.

Prepare for class on Thu Sep 17

Create a new project, using the guidance from above. Use it to experiment while you work through the following notes.

.

Supporting all relevant HTTP methods

Our code example today will help you learn to support all relevant HTTP methods.

In addition, you will learn to create the correct response, which will be an error (as noted in a later section), or one of the results in the following table.

Request

Return type

Status code

Comment

GET collection

Collection

200

GET collection

Empty collection

200

“Empty” is not an error condition

GET one

One

200

GET one

No item

404

Truly is ‘not found’

POST add item

The added item

201

Added item typically includes an identity property

PUT item updated

The updated item

200

DELETE item

(no content)

204

The response body for DELETE requests have not been defined

.

Coding principles

In the later section (“HTTP status codes for errors), you will learn that our manager methods will return data, or null.

In our controller methods, the return types will be as follows:

Get all – return an entity collection, typically in an IHttpActionResult (second-choice alternative, an IEnumerable<T>)

In the manager, “add new” attempts to add a new object. The object’s data passed input data validation in the controller, so the attempt should succeed. In the future, you can add business logic here if you need additional validation to be done.

Return the appropriate resource model type.

In the controller, you must first check the model state (i.e. input data validation). If the data is bad, return BadRequest().

If you have a well-designed resource model class, and use data annotations, the quality of the input data rises.

In addition, this step guards against under-posting (missing data), and over-posting (too much data).

If successful, call the manager method. Then, return a Created() result, along with the new object.

The Created() result requires you to supply a URI for the new object. The runtime will use that URI as the value of the Location header. To construct a URI, use the “new Uri” constructor. The Url.Link method is a helper method (System.Web.Http.Routing.UrlHelper). The method takes two arguments:

A route name, which can be seen in App_Start/WebApiConfig.cs, and

A route value, which we get from the new object’s “Id” (identifier) property

The “route name” will resolve to a URI that effectively is the base URI to this controller’s actions. The “route value” is then appended.

.

“Update existing” explained

In the repository, “update existing” first attempts to fetch the existing object. If the existing object does not exist, null is returned.

Alternatively, if successful, it has a reference to the object, and will proceed to update the object, and then return the updated object:

ds.Entry(p) is the reference to an object “p”

.CurrentValues is the object’s collection of current values

.SetValues(updatedP) will update/change those values with the new supplied values

The SetValues method ignores missing properties, as well as navigation properties to associated objects.

In the controller, you must first check the model state. At the same time, for “update existing” scenarios, you must ensure that the identifier on the URI matches the identifier in the request entity body. If the data is bad, return BadRequest()..

This step guards against some kinds of attacks.

Alternatively, if successful, call the manager method. If successful, return an Ok() result and the updated object.

.

“Delete existing” explained

In the manager, “delete existing” first attempts to fetch the existing object. If the existing object does not exist, do nothing (but in the future, we’ll fix that).

Alternatively, if successful, it attempts to remove the existing object from the collection. This attempt is guarded by a try-catch block. The attempt may fail, because the existing object may be associated with other objects.

In the controller, we simply call the manager method. We don’t care if the object exists, because we don’t want to reveal too much information (to the requestor) about our entity collection.

.

Which controller method executes?

You have learned that an ASP.NET Web API web service uses the front controller pattern to determine which method in which controller to run when a request is received.

How does the algorithm work?

Before we cover the steps, think about the data that could be part of a request. A request could include simple data types, and/or complex data types.

Simple data types – in the URI and/or query string – include:

int, single, double, decimal

string, byte, char, bool, guid

datetime, timespan

Complex data types – in the message body – include:

anything else; typically any instance of a class

your own classes, or .NET Framework classes

one-of, or collections-of

Here’s the algorithm:

1. The URI is inspected, looking for a controller name match

2. The HTTP method is inspected

3. The request’s data is inspected – data could be part of the URI and/or query string, or in the message body

In this version, our manager methods will return data, or null. The null value will indicate that there’s no data, or an error.

In our controller methods, we will interpret null as ‘no data’ or an error. Its meaning will depend on the method’s context.

Later, our ‘version 2’ strategy will be extended to handle additional kinds of errors, in a way that covers the entire application, with less code to write and maintain.

.

Data annotations overview

Most students in the course are familiar with data annotations. This section will refresh your memory, but with a web service focus. If you need to learn about data annotations, continue reading and studying.

Data annotations are descriptive text attributes that we add to properties in a class. A data annotation is located just before/above the property declaration.

Data annotations can help with:

property constraint and limits

input data validation

property display and formatting in views

communicating error messages to users

Some data annotations are intended only for design model classes, while others are for use with resource model classes. And, some work with both.

Their overall benefit is to reduce the amount of code that has to be written to handle typical data management scenarios.

Please note that data annotations DO NOT replace the need to validate data against business rules and/or application logic. You still need to do that. Data annotations help most by improving the quality of input data, so that it can then be inspected for its integrity and appropriateness.

In a regular expression, sometimes you need the backslash character (e.g. \d). In a .NET Framework string, the backslash is a quote character. So, you either precede the entire string with an at sign (@), or use a double backslash (\\d).