Monday, December 29, 2014

Creating a Windows Communication Foundation (WCF) Service

WCF services


Tens of thousands of Web Services exist on the web. They are code that that is served up by a web services such as IIS or Apache at a user's request. They usually have an HTTP or IP address. These services have no visible interface in the sense of a web page or form. They just offer an Application Programming Interface (API), that is a set of methods that can be called, the parameters they require, and what they will return. It is up to the web developer who uses the services how to display the data they return.

Most of these services offer access to data from databases: Travel information, hotel vacancies, stock market transactions, etc. Many cost money to access. Services are a secure way to manage these transactions. The web developer never touches the database directly. Everything is passed through the service. The service can validate and ensure the safety and integrity of the data.

Designing software around services is known as "Service Oriented Architecture." This doesn't replace object oriented programming; it incorporates it. The service is designed using objects.

One more word on Services. Most fall either into one of two technologies: "Soap" or "Rest." Soap uses XML to transmit the data from the service to the client. The XML is complex. It uses a Soap envelope, that encloses an XML Schema that describes the class and its methods. Additionally a WISDL file is included or generated which can be used to 'Serialize' a class in the target language. Rest uses Javascript and is much simpler. It passes the information in JSON name value pairs. This is lighter weight, but includes less information. Still Rest is the more popular protocol. We will be using SOAP because that is what Visual Studio renders by default.

Finally, for this exercise we are not going to host the service in IIS proper. This would require a great deal of configuration and set up. Instead we will have to run two or more copies of Visual Studio at the same time. One will have the service and one the client.

The Register, Log In Service


For this exercise we will create a web service that allows the user Register as a reviewer, log in and add a new book and a review.

Start Visual Studio and open an Empty Web Site. Name it BookReviewRegistrationService

The first thing we will add is the ADO Entites. Name it BookReviewRegistraionModel

Choose Existing database and make a new connection using the SQL Server login "ReviewerLogin" with the password "P@ssword2."

Choose the tables "Reviewer" and "CheckinLog."

Before we go on add the PasswordHash, KeyCode, and LoginClass from the previous assignment. You can get them by right clicking on the project name, choosing ADD, EXISTING ITEM and scrolling to the project where the classes reside. Select them and click Open.

Next we want to add a WCF Service. Right Click on the project and select ADD new Item. Choose WCF Service--not Data Service or the Ajax enable service. Name it "ReviewerRegistrationService."

This will add two things to your App_Code Folder: an iterface IReviewRegistrationService.cs and the Service itself, ReviewerRegistrationService.cs. We must first deal with the Interface. It looks like this at this point.

A couple of notes: An interface is an abstract structure that only contains method signatures. It is sometimes referred to as a "contract." A class that implements an interface must give a body to all its methods. In our case we want to add methods to register a reviewer and to allow a reviewer to log in. Delete Void DoWork() and add our own methods. We also need to add a Data Contract a Reviewer lite class that we can pass from the WebPage. In fact, let's call it "ReviewerLite." Here is the code:

Now we will turn to the service itself. Open it. It will look like this.

Click the interface. This will put a small blue underline under the first letter of the interface. Mouse over it to expand it. It behaves like a smart tag in Word. When it is expanded select implement interface.

Now your Service class should look like this:

You can delete the public void do work. We will fill in the other two. First we will add a reference to the Data Entities:

Next we will work out the Register Reviewers method. If you look at the logic of this method, it is a lot like what we did last assignment:

1. Instantiate PasswordHash()
2. Instantiate Keycode()
3. Pass the password and keycode to PasswordHash to get the hashed password
4. instantiate a new instance of the Reviewer class from the data entities
5. map the fields from ReviewerLite to Reviewer
6. assign the new hash and the seed to the Reviewer fields
7. add this instance of review to the collection Reviewers
8. save all the changes to the database

Here is the code:

I put the code in a try catch so that the calling web page can have some indication if the registration succeeded. If something goes wrong the boolean will return false.

The Log in method will also resemble the previous assignments log in. It is actually very simple, because the LoginClass does all the work.

Make sure you have service selected and run the program you should get something like the following

The x's are because we didn't implement asynchronous versions of the methods. Ignore them. It will be hard to test the registration, so lets test the Login method. Double click it. You should see something like this.

We need to provide a valid username and password. Use the one from the last assignment. In my case it was "spconger" and "pass." Click the Invoke button, and click through the security warning. Notice the method returns "1," which is the id of my user. If you enter an invalid user or password it should return "0."

Finally, click on the XML tab. It will show you the structure of the request and the response XML. These are generated for you by .Net, but in other languages you might have to code them by hand.

Now we will make another WCF service to Add a new Book, Author and review

New Review


Think about what is needed to add a review. First we must determine if the book is already entered. If not we need to enter it. The same with the artist. In the client app we can solve these by having lists of artists an books. The user can choose a book or enter a new one, same with the artist. So we need methods for entering a book, a review and an artist. They should also be able to select a genre. This all looks a bit complicated, but it's not as bad as it seems. Let's give it a shot.

Leave the current visual studio open. Right Click on the visual studio icon in the tray and select visual studio 2013. It will open another instance of Visual Studio. Create a new empty web site. Call it "AddReviewService." Add the ADO Entities. Name the model "BookReviewDB." Use and existing database, new connection, Sql Login, ReviewerLogin, "P@ssw0rd2". Select these tables:

The diagram should look like this.

Now add the Service. Call it "NewReviewService."

We will have operation contracts for the following Add Review, Add Author, Add Book. We will also need methods for Getting books, getting Categories and getting authors.

Notice the Add books method. In it we take in a Book object, an author object and a string with the category name. This is because of the many to many relationships between Book and Author and Book and Category created by the Data Entities. For simplicity, I have implemented it so that we can only add one author and one category for a book. To make it work for multiple artists and multiple categories we would need to pass not an Author object and an array of Authors (Author[] a) and an array of Category names (string[] categories). That also would complicate our client application. Though you might try to implement it as a challenge exercise.

Open the service and implement the interface.

Here is the code for the AddAuthor method. Notice that the Entities Context was declared a class level.

Here is the add book method. Note that it takes advantage of ADO Entities ability to manage relations between entities. Also you might note the strange operator used in the Category and Author sections "=>." This is called a "Lambda" operator. Microsoft's definition is, as usual, a bit vague and only marginally helpful:

A lambda expression is an anonymous function that 
you can use to create delegates or expression tree types. 
By using lambda expressions, you can write local 
functions that can be passed as arguments or returned 
as the value of function calls. Lambda expressions 
are particularly helpful for writing LINQ query expressions.

But there are a few instances where we will need them. The Add review method which follows is one of them.

The Add Review Method.

Here the Lambda expression is used in a if statement. I had trouble making sure that the Book object had a valid key. This guarantees that it does.

We also need methods for returning Books, the names of the authors and categories. Here is the code for these three methods:

Run the service to make sure it works. Here I added an author "Neil Gaiman." It returned true.

If I go to the Tools menu and start a new query, I can confirm that the author was indeed written.

No comments:

Post a Comment