Showing posts with label Data Access. Show all posts
Showing posts with label Data Access. Show all posts

Friday, May 1, 2009

Silverlight 2, WCF, and Lambda Expressions - Part 1

This is a 2-part series in using WCF with Silverlight 2. Part 1 is about creating a Silverlight-compatible WCF service and consuming it in a Silverlight application. Part 2 is about lambda expressions, but uses the foundations in Part 1.

Step 1 - Create a New Silverlight Application
First we'll create a new Silverlight application. In Visual Studio, create a New Project, and select the "Silverlight Application" template. I've called mine "SilverlightWithWCF", so that's what you'll see in a couple places throughout the post.

Visual Studio will prompt you with the following:
(Click image to enlarge)


We want to include a new ASP.NET Web Application Project, so we'll leave the defaults as-is. Other options include "ASP.NET Web Site" and possibly "ASP.NET MVC" (if you have the MVC bits installed). In addition to using the ASP.NET application as a test site for the Silverlight application, we will use it to host our WCF service.

Step 2 - Build the WCF Service
We'll add a new WCF Service at this point. Right-click on the Web Application project ("SilverlightWithService.Web" in my case), and choose "Add", then "New Item". Select the WCF Service. We'll name ours "PersonService.svc". See below:

(Click image to enlarge)


You'll notice that there are 2 options we could choose from: "WCF Service" or "Silverlight-enabled WCF Service". You might wonder why we didn't pick the Silverlight one. The answer is that I wanted to look at the standard WCF Service, so that you will know what to do if you already have an existing WCF Service that you want to hook into. I'll point out the difference below when we look at the Web.config file.

Step 2a - The WCF Service Contract
WCF Service consist of 3 main pieces: the Service Contract, the Service Implementation, and the Service Configuration. First, we'll look at the Service Contract.

The contract is simply an interface decorated with a few specific attributes. Visual Studio will create an I[ServiceName].cs file that contains the placeholder contract. If you open the IPersonService.cs file, you'll see an interface that is decorated with the [ServiceContract] attribute. Visual Studio also gives you a sample method called "DoWork". You'll notice that this is decorated with the [OperationContract] attribute. You can think of this as being analogous to the [WebMethod] attribute that we used in ASMX Services. The [OperationContract] attribute denotes which methods will be exposed to the outside world.

We're going to replace the "DoWork" method with a "GetPeople" method. Take a look at the completed code below, and we'll step through it:

(Click image to enlarge)


You'll notice that our method returns a List of Person. Person is a custom class, and so we need to include the definition of the class as well. You'll notice that we have a separate public class called "Person" that is decorated with the [DataContract] attribute. The class consists of 2 public properties (FirstName and LastName) that are each decorated with the [DataMember] attribute. The DataContract and DataMember attributes let the WCF sub-system know that it needs to include this type in the definition of the Service.

On a side note, the [DataContract] and [DataMember] attributes can be excluded in this particular case. .NET 3.5 SP1 will automatically include the type definition for public classes that have automatic properties and a public default constructor. This was added to facilitate Entity Framework. I'll leave it as an exercise for the reader to do further research into this.

The contract only tells what the service will do, not how it does it. For that, we'll need to look at the service implementation.

Step 2b - The WCF Service Implementation
The WCF Service implementation is a class that implements the WCF interface. Open up the "PersonService.svc.cs" file (note: you can simply double-click on the "PersonService.svc", and it will open the .cs file).

You'll see that the class "PersonService" implements "IPersonService" and still has the placeholder "DoWork" method from the stub that Visual Studio created. Delete this method. We'll let Visual Studio add the stubs for the updated interface. Simply right-click on "IPersonService" and select "Implement Interface", then "Implement Interface" again (we won't cover "Implement Interface Explicitly"). This will create a stub for the "GetPeople" method. Here's the implementation:

(Click to enlarge image)


This simply creates a List object and populates it with some Person instances. In real life, you'll probably be doing something more complex (such as accessing a database).

Next comes the configuration.

Step 2c - WCF Service Configuration
Open up the Web.config file, and then navigate to the "system.serviceModel" section (at the bottom). The only thing that you'll need to do is update the binding to "basicHttpBinding" (from "wsHttpBinding"). See below:

(Click image to enlarge)


Remember when I promised to show the difference between "WCF Service" and "Silverlight-enabled WCF Service"? This is it. Silverlight 2 is limited in that it can only use WCF Services that use the "basicHttpBinding". This is the same binding that ASMX services use. (Note: Silverlight 3 will not have this limitation). The "Silverlight-enabled WCF Service" defaults to basicHttpBinding, while "WCF Service" defaults to wsHttpBinding. If you have an existing service, you'll just need to change this value (or add an endpoint that uses this binding).

Note: This is a very important step. If you try to add a Service Reference in a Silverlight application to a WCF Service that is *not* using basicHttpBinding, then the proxy will not work. Even better, you don't get any helpful error messages, just a rather obscure one. So, make sure you don't skip this step.

From here, we'll build everything just to make sure that things look good. This completes our updates to the Web Application. Next, we'll move on to the Silverlight application.

Step 3 - Add the WCF Service Reference to the Silverlight Application
We'll start in the Silverlight application by adding a Service Reference to our newly created service. Right-click on the Silverlight Application project ("SilverlightWithService" in our case), and choose "Add Service Reference". If you click the "Discover" button, it will search out the Services that are included in the Solution. We'll use the namespace "PersonService". See below:

(Click image to enlarge)


Before you click "OK", be sure to check out the "Advanced" button. This opens a dialog that lets you choose how collections are returned from WCF Service calls:

(Click image to enlarge)


You'll see that there are 4 options to choose from: Array, Generic List, Collection, and ObservableCollection. The ObservableCollection is preferred in Silverlight for data binding purposes, but you may want to experiment with the other options as well. It doesn't matter the actual collection type that is returned from the service; it will be converted to the type you select here.

Now that we've added our Service Reference, we'll take a look at the Silverlight UI.

Step 4 - Update the XAML
Next, we'll create the UI. Open up the Page.xaml file. We're going to be making a few changes to the default values and adding some controls of our own. The final layout may look a little odd. This is because we will be adding some more elements to this in Part 2.

Here's the final layout:
(Click image to enlarge)


Let's look at the XAML; then we'll go through it step by step:
(Click image to enlarge)


First, update the Width and Height of the UserControl to 600 and 200 respectively. Then we'll swap out the "Grid" root element for a "Border". Then add a Grid with 3 columns (the other 2 columns will be used in Part 2). Inside the first column is a StackPanel with a ListBox and a Button. The ListBox sets the ItemsSource to "{Binding}". This says that each ListBox item will be bound to each item in the collection. The data binding will use a DataContext that we set in code at runtime.

Next is the Button named "EHButton" (for Event Handler Button -- Part 2 will have 2 additional Lists and Buttons and these names will make more sense). When adding an event handler in XAML, Visual Studio will help you out a bit. If you type "Click=" and hit Ctrl-Space (or let Intellisense pop up on its own), you will have the option "New Handler" to pick from. This will automatically name the handler based on the control name, and then add the stub to the code. In this case, it will create "EHButton_Click" in the code and hook up event.

Now that our UI is laid out, let's put the last of the pieces together.

Step 5 - Call the WCF Service
Here's another short-cut. If you right-click on "EHButton_Click" (the event handler) in the XAML, one of the options is "Navigate to Event Handler". This will open up the Page.xaml.cs file and put the cursor on the "EHButton_Click" event handler.

First, add the WCF Service namespace to the "using" section. This will make the code more readable. The namespace is [projectName].[serviceNamespace]. In our case, it is "SilverlightWithService.PersonService".

Now, we'll go back to the event handler. Start by creating a new proxy object. The proxy is the service name with "Client" appended to the end. In our case it is "PersonServiceClient". Next we'll hook up the callback. Since all Silverlight calls are asynchronous, we have to call the service asynchronously (it's the only choice). Start by hooking up an event handler to the "Completed" event. Visual Studio helps you out with this, too. Type "proxy.GetPeopleCompleted +=", and you'll see Intellisense for creating a new event handler. If you press "Tab" twice, it will create the new handler, and add the implementation. This is a great short-cut. The last step is to call the service using the "Async" method. In this case, just call "proxy.GetPeopleAsync()". See completed button click event handler below:

(Click image to enlarge)


The final step is to implement the callback. This is as simple as getting the result of the call (in this case a List of Person) with "e.Result" in the code. Then we assign this to the DataContext of the ListBox in the UI. One thing to note, if you hover over "e.Result", you will see that it is actually of type ObservableCollection of Person. This is due to the selection we made when we added the Service Reference earlier. The completed Page.xaml.cs file is as follows:

(Click image to enlarge)


Step 6 - Build and Test
Let's build and run. What you should see is that when you click the "Event Handler" button, you will get a list of 5 names in the ListBox. This may take a few seconds for the Service to fire up and run -- remember we're running asynchronously here. Also note that the list only includes the First Name because we did not do a full data template; we just set the DisplayMemeberPath. It's easy enough to enhance yourself, though.

(Click image to enlarge)

Conclusion
You should have a pretty good idea of how to create a WCF Service and consume it with Silverlight 2. We've created a new WCF Service, ensured that it was Silverlight 2 compatible, created a Silverlight 2 application, added the Service Reference, updated the UI, and finally called the Service and bound the results to the UI. In Part 2, we'll be looking at other ways of handling the asynchronous calls.

Tuesday, April 14, 2009

Book Review - Data-Driven Services with Silverlight 2

As mentioned in a previous post, I deal with data-centric applications on a daily basis. Data-Driven Services with Silverlight 2 by John Papa is an excellent book for folks in the same situation. Here's what I really like about it:
  • Focused Topic
  • Concise Code Snippets
  • Clear and Useful Samples
  • Full Coverage of Silverlight 2 Data Access

Let's take a look at each of these.

Focused Topic
The book covers only data access concepts in Silverlight 2. It assumes that you have a basic Silverlight background and does not focus on areas such as controls, XAML or layout. This keeps the book brief (around 350 pages) and allows you to focus on the relevant topic: data in Silverlight 2.

Concise Code Snippets
Code snippets are used liberally throughout the text, both XAML and C#/VB code. The snippets build on previous samples and so only show the "new" parts. This keeps the code snippets short and relevant. And even though the code shows both C# and VB, neither seems to be too long or distracting. I found myself even forgetting that the "other" language was included at times. (You should be able to figure out which language I'm referring to -- not that there's nothing wrong with it. Both languages are pretty much equivalent, so it's just a matter of preference when it comes to syntax.)

Clear and Useful Samples
The samples (downloadable from John Papa's webite) are very clear. When there are multiple examples covering a single topic, they are packaged into a single application. This makes it very easy to navigate the samples both at design-time and run-time.

(Click image to enlarge)

A couple things to notice in the screen-shot. First, the menu system on the left. This lists the different samples that are included in the project. This makes it very easy to flip back and forth to make comparisons among the samples.

Second, notice that the sample on the right is pleasant to look at. I know that this isn't really all that important. But, many times sample applications for data access methodologies are merely functional. These actually use a custom control template library to make the samples look less generic. The control templates are out of the way in the samples, so it is still easy to focus on the functionality when reviewing the XAML.

Full Coverage of Silverlight 2 Data Access
Finally, since this book is focused simply on data access, it can cover a variety of data sources and methodologies. Chapters 1-4 are overviews of the technologies used in data access in Silverlight. Chapters 5-11 cover specific data sources. Here's a breakdown of the book chapter by chapter:

  1. Getting Started with Silverlight 2
    A few Silverlight 2 basics (such as Data Services and the Control Model) and .NET topics (such as LINQ and C# language enhancements) which are needed in later topics such as data binding.
  2. Silverlight Data-Binding Foundation
    The data-binding basics including dependency properties, XAML binding markup, and the DataContext.
  3. Modes and Notifications
    OneTime, OneWay, and TwoWay binding modes and the INotifyPropertyChangedInterface.
  4. Managing Lists, Templates, and Converters
    An overview of working with list-based controls, implementing data templates, and building value converters.
  5. WCF, Web Services, and Cross-Domain Policies
    How to build and call ASMX services, and also using WCF services that are compatible with Silverlight 2.
  6. Passing Entities via WCF
    How to send entities (simple classes) back and forth using LINQ to SQL and Entity Framework.
  7. Consuming RESTful Services with WebClient and HttpWebRequest
    An introduction to REST and using WebClient (simpler) or HttpWebRequest (more complex, but more flexible) to interact with RESTful services.
  8. Consuming Amazon's RESTful Services with Silverlight 2
    A specific example interacting with Amazon to search items, create a shopping cart, and add items to that cart.
  9. Creating RESTful Services and Introducing SilverTwit
    More REST, including consuming JSON services. The SilverTwit sample uses a series of services to create a Twitter client in Silverlight.
  10. Syndication Feeds and Silverlight 2
    How to interact with RSS and Atom feeds.
  11. Silverlight 2 and ADO.NET Data Services
    An overview of ADO.NET Data Services and how to interact with them with Silverlight.

Summary
If you create data-centric applications and are working with Silverlight 2, you need this book. By the time I got to the end of this book, I was extremely comfortable creating services and consuming them with Silverlight. This is an excellent addition to my collection of reference books, and I am finding myself repeatedly opening up the sample applications to review different data access techniques. I am very glad that I came across this excellent resource.

I read between 8 and 10 technical books per year (generally in the 500 to 900 page range). I find the majority of them useful, but occasionally one will jump out as being particularly relevant. That is how I felt with Data-Driven Services with Silverlight 2.

Saturday, April 4, 2009

Getting Started with Silverlight 2

I was planning on doing my next application at work in WPF, but it turned out that Silverlight 2 was a better fit. So, I've been doing some quick and dirty work to get up to speed. The good news is that the UI model with XAML is pretty similar (I'll let others get into the specific differences). The bad news is that everything happens asynchronously. Okay, so that's not really bad news, it's just something to get used to. I'll be covering some of my specific learnings on asynchronous programming a bit later, so stay tuned.

Database Programming
As I said earlier, I write business applications for a living. And that means database access. Silverlight does not support direct database access (such as ADO.NET or LINQ to SQL), so that means that everything happens through network calls. WCF is the best choice for this (with some limitations).

It took me a while to get comfortable with this concept. The best introductory resource that I found is actually on the silverlight.net site, including very useful tutorial videos. The most helpful one for me was #58 "How to Consume WCF and ASP.NET Web Services in Silverlight" by Tim Heuer. It's about 23 minutes and definitely worth the time.

Here's the short version:
  1. Create a WCF Service using basicHttpBinding (Silverlight 2 only supports this binding).
  2. Generate a proxy class for the service in the Silverlight application using the standard Add Service Reference.
  3. Create an instance of the proxy.
  4. Hook up a call-back by assigning a handler to [methodName]Completed. Visual Studio is good at helping create the stubs for you (see the video for a demo).
  5. Call the [methodName]Async() to kick off the call.
Resources
If your applications are data centric, then you will definitely want to check out John Papa's book: Data-Driven Services with Silverlight 2 -- with an introduction by Tim Heuer. This book is all about data access, whether you are creating your own services or consuming existing services. This is a relatively short book (at about 350 pages -- small for a tech book), but the text and samples (easily available for download) are very good. By the time that I got to the end, I was so comfortable with consuming services with Silverlight and working with the asynchronous calls that I could code them up with my eyes closed. I'm planning on doing a full review of this book in a later post.

The official Microsoft site has a lot to offer. In addition to the video mentioned above, there are lots more on all different topics. Just check out http://silverlight.net/Learn/.

I mentioned the Matthew MacDonald WPF book in a previous post. The good news is that there is a sibling Silverlight book: Pro Silverlight 2 in C# 2008. This is a very good overview of Silverlight 2 including XAML basics, layout, controls, animation, styles/templates, service calls, and browser integration. The accompanying samples are also very good and cover all of the included topics.

I always point to dnrTV for good web-casts. You can check out episode #127: Shawn Wildermuth on Silverlight 2 Data. Lots of interesting tidbits scattered throughout.

My Experience So Far...
Silverlight 2 is an adventure. It's not quite web programming, and it's not quite WinForms programming. It sits squarely between the two. More details coming up...