In the previous part of this tutorial we showed you how to build a simple line chart which loads its data from an exported Excel XML Spreadsheet or from a serialized list of points (in XML format). In this part we will show how to load chart data from an Astoria service.
Topics covered:
- creating ADO.NET Entity Data Model
- creating Astoria service
- using Astoria service using the Astoria client for Silverlight
What is Astoria anyway?
Astoria is the code name of a new Microsoft technology that enables applications to expose data as a data service that can be consumed by web clients over HTTP. To perform operations against the service you just have to use standard HTTP verbs such as GET, POST, PUT and DELETE. The data is represented in simple formats as XML or JSON which make Astoria extremely useful for back-end for Rich Internet Applications.
Integration
Prerequisites
To open the solution you will need Visual Studio 2008 Beta2, the Silverlight 1.1 Alpha Tools, the Astoria toolkit (VS2008 Beta2 Refresh) and the ADO.NET Entity Framework Beta 2.
Visual Studio 2008 final version is released but the Astoria toolkit is still not available for it so for now we should fit to these versions. We will provide an updated source code when the Astoria toolkit is available.
The basics
We’ve done a couple of minor changes to the chart control. They will allow us to control the way the chart data is loaded in and thus the data can be loaded from the Astoria service.
Actually we just move the two methods (LoadChartDataFromPointArrayXml and LoadChartDataFromExcelXmlSpreadSheet) we have been using to load the data in a separate class, outside the control’s project. So now you just set the data to the chart control and it draws the line. The chart control doesn’t care about who is loading the data and how it is being loaded – it just takes a List<Points> and handles the drawing. So now we have a ChartDataLoader class which we will use to load the data.
The Astoria service
To show you an example of creating and using an Astoria service we will use the sample Northwind database that ships with the SQL server editions.
Astoria models the data exposed through the service using Entity Data Model (EDM). This organizes the data in the form of so called “entities”.
So let’s start with creating the entity model. To do this: right click on the SimpleLineChartTestApp and choose Add -> New item and then select “ADO.NET Entity Data Model”. This opens a wizard that will guide you throughcreating the entity model. First, you have to specify what the model should contain – select Generate from the database.
Next you should choose your connection string to the Northwind database.
Now it’s time to select the data objects. For simplicity select only the Tables. Remember also to choose a namespace.
Click Finish to let the wizard create your Entity Data Model.
This creates two files – Northwind.edmx and Northwind.Designer.cs (if you choose Northwind for the name of the entity data model). If you open the Northwind.edmx you will see a diagram of all the entities you’ve just created.
Now we can continue with the Astoria service. Again add a new item to the SimpleLineChartTestApp but this time choose Web Data Service from the templates and name it Northwind for example. This creates a Northwind.svc and a Northwind.svc.cs files. In the code file the only thing you need to do is to replace the auto inserted /* TODO: put your ObjectContext class name here */ text with the class name of the Northwind database entities you create in the previous step. The class is named NorthwindEntities by default if you choose the Northwind database, which is in the NorthwindModel namespace.
That’s all we need to do so as to configure the service. YES IT IS THAT SIMPLE! When we started dealing with Astoria we were also surprised at first how easy is to create the service. Now hit build and run the application to test it. Go to http://localhost:port/Northwind.svc - you will see an XML representation of the data from the Northwind database.
Using the Astoria service
Now when we have the Astoria service we will get data from the Orders table and filter it a little bit.
The Astoria uses URLs to fetch specified data and process it. Consequently so as to get all orders from the database you need to request the following URL:
http://localhost:port/Northwind.svc/Orders
Now let’s have a little fun with the data. What if you want to see only the orders shipped to Germany? Try this:
http://localhost:port/Northwind.svc/Orders[ShipCountry eq ‘Germany’]
We can also filter the results by date and get the orders made only between 1st January 1998 and 1st January 1999.
http://localhost:port/Northwind.svc/Orders[ShipCountry eq ‘Germany’ and RequiredDate gt '1998-1-1' and RequiredDate lt '2000-1-1']
Dude that was easy! I hope you would like Astoria just as much as we do!
Ok, now you know which URL to hit to get the data you need. But we need to do this programmatically. In the Page.xaml.cs class of the SimpleLineChartConsumer project we will write the steps to load the data from the Astoria service and create a List<Point> object that is then passed to the chart. When we make the request to the service it returns an Order object but our application doesn’t know anything about this object so we have to create it. For simplicity our class Order contains just one property Freight that we will use for the chart data.
public class Order
{
public double Freight { get; set; }
}
We make the request to the server using the following lines:
WebDataContext ctx = new WebDataContext ( new Uri( HtmlPage.DocumentUri,
"Northwind.svc" ).ToString() );
WebDataQuery<Order> dataQuery = ctx.CreateQuery<Order>( "/Orders[ShipCountry
eq 'Germany' and RequiredDate gt '1998-1-1' and RequiredDate lt '2000-
1-1']", QueryOption.IgnoreMissingProperties );
dataQuery.BeginExecute( new AsyncCallback( DataLoadComplete ), dataQuery );
The first line creates a new object of type WebDataContext and receives the URL of the service as parameters. The WebDataContext represents the runtime context with given data service. Then, on the 2nd line we create a WebDataQuery object which represents our particular query against the specified store by the Astoria URL syntax. The Astoria Silverlight API supports asynchronous operations. This is absolutely a must for a RIA application to make an async request. So as shown at the 3rd line we call the BeginExecute method and pass a new AsyncCallback that will be called when operation is completed. Here is the DataLoadComplete method:
private void DataLoadComplete( IAsyncResult r )
{
if ( r.IsCompleted )
{
List<Order> dataList = null;
WebDataQuery<Order> dataQuery = ( WebDataQuery<Order>
)r.AsyncState;
dataList = new List<Order>( dataQuery.EndExecute( r ) );
chartAstoriaStocks.AddChartLine(
ChartDataLoader.LoadChartDataFromOrderList( dataList, 10) );
}
}
This method just checks if the request is completed and if so it calls the EndExecute method to end the request execution and to return the response. The ChartDataLoader.LoadChartDataFromOrderList accepts List<Order> and xStep as parameters and returns a List<Point> object with the loaded data in it. Assuming chartAstoriaStocks is already a created chart we call the AddChartLine* method and pass the chart data.
* AddChartLine method is new in the version of the chart line control. Currently it is not properly named but in the next version we will support multiple lines in the chart so thinking for the future we consider it would be better to name it now.
Summary
Working with Astoria is pretty straight-forward, simple and easy, but yet powerful. We think it will be used by lots of AJAX-enabled and feature-rich applications in the future. In this part have given you a brief example of how it can be implemented and used in a Silverlight project.
In this part we have added a useful feature to the chart project so now it should be quite easy for you to manage the chart data. Also with the ability to load the data from a service your chart is alive. When you update the data in your database the chart is updated and you don’t need to do anything. So go and use it and let us know if you like it ;)