-
We recently released a CTP of the next set of things we are working on for ADO.NET Data Services. We are calling this new set of features v1.5 because they are built on top of ADO.NET Data Services v1.0. ADO.NET Data Services v1.0 was included as part of the .NET Framework 3.5 SP1 and so the CTP also was built to use .NET 3.5 SP1 and Visual Studio 2008 SP1. Microsoft recently released a beta of the next version of Visual Studio and the .NET Framework and even though the CTP was not built with the new Visual Studio it is still possible to use it.
The rest of this blog will walk you through the steps for using ADO.NET Data Services v1.5 CTP1 with Visual Studio 2010.
Requirements:
- Visual Studio 2010 Beta 1 installed
- ADO.NET Data Services v1.5 CTP1 installed
- A good working knowledge of how to use ADO.NET Data Services
Part 1: The ADO.NET Data Service
Visual Studio 2010 includes the tooling required to build a Data Service, but by default it will build a v1.0 data service. If you have an application and you select “Add -> New Item” you will only have the option to choose a standard v1.0 Data Service.
Even though you have installed the ADO.NET Data Services v1.5 CTP1, the CTP1 Data Service option does not show up in the list as it does in Visual Studio 2008. To get around this restriction, we will create the data service and modify it to run using the v1.5 CTP1 runtime. Create the service normally and then examine the “References” node in the solution explorer. You will see that it has added references to System.Data.Services and System.Data.Services.Client.
To move to using the v1.5 CTP1 features, you must change those references to use the CTP1 assemblies. The first step is to remove those two references (use right-click). After removing the references, right-click the References node and select “Add Reference”. In the Add Reference dialog, select the “Browse” tab and move to the install location for ADO.NET Data Services CTP1. By default this is:
“C:\Program Files\ADO.NET Data Services V1.5 CTP1”.
Under the bin folder you will see the two assemblies, Microsoft.Data.Services.dll and Microsoft.Data.Services.Client.dll.
Select both assemblies and click OK. The references view should now look like this:
Your service will now use the CTP1 assemblies and have all of the CTP1 features. To prove this, I will try using a v1.5 CTP1 feature; I will run my service and navigate to the Customers entity set and add the $count segment. If I do this I should get back the count of Customers in my service.
http://host/service.svc/Customers/$count
I now have a v1.5 CTP1 version of my Data Service with all of the v1.5 features.
Step 2: The client.
Now that I have a v1.5 CTP1 service end-point, I want a v1.5 CTP1 client that can talk to my service. The client is a little trickier. I can use the same process on the client as I did on the service to update my assembly reference to point to the new client assembly and get a v1.5 client.
Where the client gets interesting is when I go to generate my client-side types that know how to speak to the v1.5 service. For both the Web Friendly Feeds and the databinding features of the v1.5 CTP1, I need special client-side types that can interpret Friendly Feeds and have the OnPropertyChanged and OnCollectionChanged events for binding. Now I could hand-craft my client side types to do this, but I would rather have auto-generated types based on my service metadata that do this for me.
Let’s walk through auto-generating v1.5 CTP1 client side types that work with my v1.5 CTP1 service. The first thing you should do is go through the “Add Service Reference” gesture and add a service reference to the service you created in Step 1.
For my client, I have created a WPF client and used the “Add Service Reference” gesture to create a set of proxy class that can talk to my Northwind Data Service from step 1.
I now have two problems.
- I have a reference to System.Data.Services.Client, which is not the v1.5 CTP1 assembly
- I have a set of client-side proxy class “NorthwindEntities” that do not have any of the v1.5 CTP1 features.
To solve the first issue, I will go through the same process as in Step 1 and remove the reference to System.Data.Services.Client and replace it with a reference to Microsoft.Data.Services.Client (see step 1 for instructions).
I have solved issue 1 but I still have client side types that do not have the v1.5 CTP1 features. To solve this issue, I will need to manually create my Service Reference as the Add Service Reference dialog in Visual Studio 10 will always use the code generation utility that ships with Visual Studio 10. The v1.5 CTP1 shipped with a command-line utility named “DataSvcUtil.exe” that knows how to generate v1.5 CTP1 client side types. This utility is located in the same bin directory as the v1.5 assemblies we referenced before. So I will open a command prompt, navigate to that directory and run the DataSvcUtil.exe utility. The parameters are
- An output class file
- A data service URI (use the service you created in step 1)
- The /binding flag [optional]. I included this because I want to turn on the cool binding feature in v1.5 to have automatic change tracking on my client side types.
The next step is to copy the output file (Reference.cs in my case) into the Service References folder of my visual studio project. I will overwrite the one visual studio created for me earlier.
I now have a client that uses the new v1.5 CTP1 features that can talk to my v1.5 CTP1 service all using Visual Studio 2010 Beta 1 and .NET 4.0 Beta 1.
-Shayne Burgess
ADO.NET Data Services, Program Manager
-
Tom Laird-McConnell has created a nice post showing how to mid-tier proxy to enable calling data services across domains. His proxy supports CRUD operations and $expand.
http://blogs.msdn.com/tom_laird-mcconnell/archive/2009/03/25/creating-an-ado-net-data-service-proxy-as-workaround-for-silverlight-ado-net-cross-domain-issue.aspx
We're hoping to add support for simple xdomain requests (ie. limited auth support, etc) in the near term and expand that support over time to get closer to parity with what we have today for same-domain requests. To help us prioritize this work we are very interested to hear how many people would use such "full" cross domain support with data services if it were available.
-Mike Flasko
ADO.NET Data Services, Program Manager
-
If you haven't seen yet, the SQL Data Services team announced some excited news at this past MIX conference. Effectively they have decided to support full relational capabilities in SDS. Much has been written about this already, including a description of how this will layer naturally with ADO.NET Data Services :). I recommend checking out these two posts on the SDS team blog:
The no spin details on the new SDS features
Accessing the New Relational SDS with REST
-Mike Flasko
ADO.NET Data Services, Program Manager
-
Phani, a member of the data services team, has continued his great series on Web Friendly Feeds with a look at how to map entity values to custom markup. You can find all his posts to date on Web Friendly Feeds here:
Part 1:Introducing Web Friendly Feeds aka Friendly Feeds
Part 2:ADO.NET Data Services Friendly Feeds , Mapping CLR Types
Part 3:ADO.NET Data Services Friendly Feeds , Mapping EDM Types - I
Providing Feedback
We have created a new forum dedicated to providing feedback on "pre-release" versions of data services such as this CTP. Please direct all your questions and comments about this feature to this new forum which is available at: (http://social.msdn.microsoft.com/Forums/en-US/dataservices/threads).
Note: The forum intended for questions on currently shipping versions of ADO.NET Data Services is still available at: (http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/threads/ )
We look forward to hearing your feedback.
-Mike Flasko
ADO.NET Data Services, Program Manager
-
We received a few questions asking if CTP1 of ADO.NET Data Services v1.5 includes a Silverlight library. The short answer is yes, we included a Silverlight library initially intended for use with Silverlight 2. Once you install v1.5 of data services, you can find the SL library in the "Program Files\ADO.NET Data Services V1.5 CTP1\sl_bin" directory. The Silverlight library is a superset of what we shipped in the Silverlight 2 SDK and includes all the same enhancements we have made to the .NET Fx-based client library shipped with v1.5 CTP1.
As a heads up, we have a known bug in ADO.NET Data Services v1.5 CTP1 when using the "Add Service Reference" Visual Studio gesture. Basically instead of setting the assembly reference to the data services client library as CopyLocal=true, the Add Service Ref sets it to false. If you have hit this issue, check out Phani's blog post here for a detailed description of the simple workaround.
Also, if you are using Silverlight 3 and want to give ADO.NET Data Services 1.5 CTP1 a spin, check out this post for instructions.
-Mike Flasko
ADO.NET Data Services, Program Manager
-
Phani, a data services test team member, has posted two nice write ups describing the "web friendly feeds" feature in the ADO.NET Data Services v1.5 CTP1 release we made available for download yesterday.
You can check out Phani's posts here and here.
Also, we have created a new forum dedicated to providing feedback on "pre-release" versions of data services such as this CTP. Please direct all questions and comments about this feature to this new forum which is available at: (http://social.msdn.microsoft.com/Forums/en-US/dataservices/threads).
We look forward to hearing your feedback.
-Mike Flasko
ADO.NET Data Services, Program Manager
-
This blog post is an introduction to the data binding capabilities we have added in Data Services v1.5 CTP1. Since this is a CTP release of this feature we eagerly look forward to hearing your feedback.
Introduction to Data Binding
In ADO.NET Data Services, it is now possible to generate client side types that implement the INotifyPropertyChanged and INotifyCollectionChanged interfaces.
A new method has been added to the DataServiceQuery and QueryOperationResponse classes called ToObservableEntityCollection that will create an ObservableEntityCollection (extends ObservableCollection) that contains the results of an ADO.NET Data Services query. The ObservableEntityCollection supports two way binding. This means that any changes made to contents of the collection will be reflected on the state of the ADO.NET Data Services client context; any subsequent calls to SaveChanges() on that context will then execute those changes against the service.
Here are some examples of different ways to create an ObservableEntityCollection using the ADO.NET Data Services client library. In all of these examples, the queries are being executed against a service named “nwsvc” that exposes two types: products and suppliers that have a one-to-many relationship.
Example 1: Creating an ObservableEntityCollection of all products.

Example 2: Creating an ObservableEntityCollection of all products and their associated suppliers.
Example 3: Creating an ObservableEntityCollection of all products and the associated suppliers from a LINQ Query.

Example 4: Creating a new ObservableEntityCollection of products. This creates a new empty collection of products without issuing a query against the service. New product objects can be created and added to this collection.

Example 5: Creating a ObservableEntityCollection of products from an asynchronous query.

Walkthrough
The following is a walkthrough of using data binding in a WPF application.
To get started, you'll want to download all of the required software I use in the walkthrough:
- Visual Studio 2008 SP1 (here)
- ADO.NET Data Services v1.5 CTP1 (here)
Step 1: Create an ADO.NET Data Service v1.5
Create a new Web Application (named DatabindingDemo):

Our first data access related task is to generate the Entity Framework-based data access layer to the Northwind database. Right click the ASP.NET project and select 'Add New Item', then select 'ADO.NET Entity Data Model'. Name the new item nw.edmx:

After clicking ‘Add’ on the screen above, a wizard will open to walk you through creating the Entity Data Model for the Northwind database. Use the default settings until you get to the point where you choose the database objects to include in the model. For this demo, choose only the Products and Suppliers tables.

Once you reach the ‘Choose Your Database Objects’ screen, select the two tables and click ‘Finish’. This will open the Entity Data Model designer view. This view allows you to customize the generated conceptual data model. To learn more about the mapping capabilities of the Entity Framework, see here. For this demo rename the Suppliers entity to “Supplier” and the Products entity to “Product”.

Create a v1.5 CTP1-based ADO.NET Data Service over this model. To create the data service, right click the ASP.NET project and select 'Add New Item'. Add an 'ADO.NET Data Service v1.5 CTP1' item called nw.svc

This will generate a file (nw.svc.cs) which represents the skeleton of a v1.5 data service. All we need to do now is point the data service at the data model to be exposed as a REST-service and we’ll be set. The snippet below shows the 2 or so lines of code you need to write to do this. One thing to note is that a data service is locked down by default, so we need to take explicit steps to open access to it. For this simple application we’ll enable read and write access to the entire model quickly using the call to ‘SetEntitySetAccessRule’ shown below.

The data service is now created. To test this, run the project and navigate to the nw.svc file. You should see a listing as shown below that outlines all the entry points to the data service. If you don’t, tweak your IE settings and reload.

Step 2: Enable data binding on the client.
By default, the client side types generated by ADO.NET Data Services v1.5 CTP1 do not implement binding interfaces. To get client side types that do implement the binding interfaces, you have to tell the code generation library that you want client code that has binding enabled. To do this, set an environment variable before starting Visual Studio and then use Add Service Reference (ASR) to generate client proxy code. The environment variable to set is:
set dscodegen_databinding=1
Note: The use of this environment variable is further explained by the video embedded in this blog post.
Note: It is also possible to generate proxy code that have binding enabled using DataSvcUtil.exe with the /binding flag.

Step 3: Create client proxy code with binding enabled.
After setting the environment variable in step 2, open the solution you created in step 1 and create a new WPF project.

Once you have created a WPF client project, the next step is to generate client side types. To do this, find the DatabindingClient project in the solution explorer, right-click the project and select Add Service Reference.. .In the Add Service Reference dialog, click the Discover button. The nw.svc service will show up in the Service window. Enter NorthwindService as the Namespace value and select OK. This wizard will generate a set of client side types that can be used to interact with the service created in step 1.

If this step is done correctly, you will see a new NorthwindService node under the Service References Node in the solution explorer. As well, you will see a reference to Microsoft.Data.Services.Client in the references node; if you do not see the reference to Microsoft.Data.Services.Client or you see a reference to System.Data.Services.Client go to the ADO.NET Data Services blog and read this post about enabling ADO.NET Data Services v1.5 features in Visual Studio and then repeat the Add Service Reference Step.

The next step is to create a new instance of the ADO.NET Data Services client context and connect to the service created in step 1. To do this, add the following code to the Window1.xaml.cs file to create a connection to the service; making sure to replace the host and port number with the values for your service.

The next step is to create an interface that you can bind the result of a query to. The service you created in step 1 exposes a set of Suppliers and a set of Products from the Northwind database with a one-to-many relationship between them. The XAML code below will create two listviews, one to display the suppliers and another to display the products associated with the current supplier selected in the first view. This type of binding is called master-detail binding.
The code below uses standard WPF binding semantics. The ItemsSource of the supplierView is set to “{Binding}”, this will cause the listview to bind to the collection of items that are supplied as the data context of the supplierViewGrid; in this case the collection of items will be a collection of supplier objects. The columns of the supplierView are each bound to a property of the supplier object through the DisplayMemberBinding="{Binding Path=SupplierID}"/> tag.
The second listview, productsView, is bound to the Products property of the supplier objects by the ItemsSource="{Binding Products}" tag.
By supplying the IsSynchronizedWithCurrentItem="True" tag on the listview, you are taking advantage of the feature WPF has to automatically display the items in the second list view (products) that are associated with the currently selected item in the first list view (suppliers).
Paste the following code snippet into the window1.xaml file:
<Grid Name="supplierViewGrid">
<ListView ItemsSource="{Binding}" Margin="25,11,33,145" Name="supplierView"
IsSynchronizedWithCurrentItem="True">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding
Path=SupplierID}"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding
Path=CompanyName}"/>
<GridViewColumn Header="Address" DisplayMemberBinding="{Binding
Path=Address}"/>
<GridViewColumn Header="City" DisplayMemberBinding="{Binding Path=City}"/>
<GridViewColumn Header="Region" DisplayMemberBinding="{Binding
Path=Region}"/>
</GridView>
</ListView.View>
</ListView>
<ListView Margin="25,213,33,0" Name="productsView" ItemsSource="{Binding Products}"
IsSynchronizedWithCurrentItem="True" Height="97" VerticalAlignment="Top">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding ProductID}"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding ProductName}"/>
<GridViewColumn Header="QuantityPerUnit" DisplayMemberBinding="{Binding
QuantityPerUnit}"/>
<GridViewColumn Header="Price" DisplayMemberBinding="{Binding UnitPrice}"/>
<GridViewColumn Header="InStock" DisplayMemberBinding="{Binding
UnitsInStock}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
Edit the following attributes of your window: Height="382" Width="584" to properly display the controls.
This will create a WPF interface that looks like this:

The final step to enable binding to these WPF controls is to set the DataContext of the grid in the window you just created to the result of a query for suppliers from the service created in step 1. This is done by executing a standard ADO.NET Data Services query on the context for the set of suppliers and then adding a call to ToObservableEntityCollection() to the result of the query. The ToObservableEntityCollection() method will execute the query against the service and return the result as an ObservableEntityCollection of entities. The entities in this collection will implement INotifyPropertyChanged and INotifyCollectionChanged. To do this, add the following code to the constructor for the window:

Once this is complete, compile the project and run it. The result should be:

Step 4: Two-way Binding
Up to this point in the walkthrough, you have set up a service, created a WPF client and bound the result of a query to the service to a pair of listview controls in the client. This type of binding you have done so far has all been one-way binding. The ObservableEntityCollection you used at the end of step 3 also supports two-way binding. This means that any changes made to the collection or items in the collection will propagate to the service when a call to SaveChanges() is made on the context.
This final step will walk you through adding buttons that will add and remove items to the collection of products and take advantage of two-way binding to have those changes propagate to the service and the backing northwind database.
To start, add the following XAML code to the window1.xaml file to create three buttons to that will add and remove a product from the list of products and save the changes to the service.
<Button Height="24" HorizontalAlignment="Left" Margin="411,0,0,4"
Name="addButton" VerticalAlignment="Bottom" Width="28" Click="addButton_Click">+</Button>
<Button Height="24" HorizontalAlignment="Right" Margin="0,0,89,4"
Name="deleteButton" VerticalAlignment="Bottom" Width="28" Click="deleteButton_Click">-</Button>
<Button Height="24" HorizontalAlignment="Right" Margin="0,0,33,4"
Name="saveButton" VerticalAlignment="Bottom" Width="50" Click="saveButton_Click">Save</Button>
After adding this code the client application will be:

The next step is to handle the click events on the new buttons and add or remove the currently select product in the list. The first thing we will need is a new product window to input the property values of a new product when one is created. To do this, create a new WPF window in your client project called ProductWindow.

After creating the window, we need to set up the product window to bind to a single instance of the product class. To configure binding in the product window, you will use the same WPF binding method you used for the supplier window, except this window will bind to a single object and not a collection of objects. Add the following XAML code into the ProductWindow.xaml:
Title="Product" Height="206" Width="296">
<Grid x:Name="productGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="171*" />
<ColumnDefinition Width="159*" />
</Grid.ColumnDefinitions>
<Label Height="26" Margin="12,17,68,0" Name="nameLabel"
VerticalAlignment="Top">Name:</Label>
<Label Margin="12,49,6,0" Name="quantityLabel" Height="26"
VerticalAlignment="Top">Quantity Per Unit:</Label>
<Label Margin="12,78,68,64" Name="priceLabel">Price:</Label>
<Label Height="26" Margin="12,0,68,35" Name="inStockLabel"
VerticalAlignment="Bottom">InStock:</Label>
<TextBox Height="23" Margin="0,23,28.018,0" Name="textBox1"
VerticalAlignment="Top" Text="{Binding ProductName}" Grid.Column="1" />
<TextBox Margin="0,52,28.018,0" Name="textBox2" Text="{Binding
QuantityPerUnit}" Height="23" VerticalAlignment="Top" Grid.Column="1" />
<TextBox Margin="0,81,28.018,64" Name="textBox3" Text="{Binding
UnitPrice}" Grid.Column="1" />
<TextBox Height="23" Margin="0,0,28.018,35" Name="textBox4"
VerticalAlignment="Bottom" Text="{Binding UnitsInStock}"
Grid.Column="1" />
<Button Height="23" Margin="19.018,0,61,6" Name="okButton"
VerticalAlignment="Bottom" Grid.Column="1"
Click="okButton_Click">OK</Button>
</Grid>
Next add the following code to the ProductWindow.xaml.cs file to set the data context to a single product and handle the ok button click event:

The final step is to handle the add, remove, and save button click events in the supplier window. Add the following code to the Window1.xaml.cs file.
Add the following code to the addButton_Click event to create a new product when the add button is selected. The following code creates a new Product object, adds it to the list of products for the currently selected supplier, and creates a new product window for the user to input the property values for the new product.

Add the following code to handle the click event on the delete button. This method finds the supplier that represents the currently selected supplier in the list view. It then removes the currently selected product from that supplier’s collection of products. This operation gets translated into a delete operation on the product object in the service. After the save button is clicked, the product entry that has been removed will be deleted from the backing northwind database.

Add the following code to handle the save button click. This button calls SaveChanges on the context which will cause any operations that have been performed on the context to be sent to the service.

Your project is now complete. You can run the form and use the buttons to add and remove items from the collection of products. When you make a change you then click the save button to persist the changes to the service.
Providing Feedback
We have created a new forum dedicated to providing feedback on "pre-release" versions of data services such as this CTP. Please direct all your questions and comments about this feature this new forum which is available at: (http://social.msdn.microsoft.com/Forums/en-US/dataservices/threads).
Note: The forum intended for questions on currently shipping versions of ADO.NET Data Services is still available at: (http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/threads/ )
We look forward to hearing your feedback.
Shayne Burgess
ADO.NET Data Services, Program Manager
-
This post is a drill down into the Server Driven Paging (SDP) feature added in data services v1.5 CTP1. Since this is the first CTP release of this feature we look forward to hearing your feedback.
What is Server Driven Paging?
This feature is best described by example. If you had a data service that exposes photos, you would likely want to limit the total number of photos a single request to the service can retrieve because the total collection of photos may be very large. This feature allows a service author to set per collection limits on the total number of entities returned for each request. In addition to limiting the number of photos returned per request, the server provides the client a "next link" which is simply a URI specifying how to continue retrieving the rest of the entities in the collection not returned by the first request.
For those familiar with AtomPub (IETF RFC 5023, section 10.1), this feature adds support for AtomPub <link rel="next" ...> elements to the data service runtime.
For CTP1 we've included server side support for this feature only. Client library support will likely come in a future CTP.
Feature Walkthrough
The remainder of this post is a step-by-step walkthrough describing how to enable and work with the Server Driven Paging feature in a data service.
To get started, you'll want to download all of the required software I use in the walk through:
- Visual Studio 2008 SP1 (here)
- ADO.NET Data Services v1.5 CTP1 (here)
The steps we’ll follow in this walkthrough are noted below. If you are already familiar with ADO.NET Data Services v1 you may want to skip down to Step 2.
Step 1: Create an ASP.NET Web Application project and create the data model to be exposed by an ADO.NET Data Service using the Entity Framework (EF) and SQL Server. Note: Any data source (EF, custom provider, etc) supported by ADO.NET Data Services could be used.
Step 2: Create a v1.5 ADO.NET Data Service which exposes the data model created in step 1.
Step 3: Enable Server Driven Paging limits on the data service created in step 2.
Step 1: Create the Project & Data Model
Nothing new yet, simply create a new Web Application (named SDPDemo).
Our first data access related task is to generate the Entity Framework-based data access layer to the Northwind database. Right click the ASP.NET project and select 'Add New Item', then select 'ADO.NET Entity Data Model'. Name the new item nw.edmx:
After clicking ‘Add’ on the screen above, a wizard will open to walk you through creating the Entity Data Model for the Northwind database. Use the default settings (selecting the Northwind DB along the way) and click the ‘Next’ button until you reach the screen shown below:
Once you reach the ‘Choose Your Database Objects’ screen, select all the Tables and click ‘Finish’. This will open the Entity Data Model designer view. This view allows you to customize the generated conceptual data model. To learn more about the mapping capabilities of the Entity Framework, see here. For this demo we’ll just use the default model created by the wizard without any customizations.

Step 2: Create the v1.5 CTP1-based ADO.NET Data Service
The next step is to create our v1.5 CTP1-based ADO.NET Data Service which we'll subsequently set Server Driven Paging limits on.
To create the data service, right click the ASP.NET project and select 'Add New Item'. Add an 'ADO.NET Data Service v1.5 CTP1' item called nw.svc:
This will generate a file (nw.svc.cs) which represents the skeleton of a v1.5 data service. All we need to do now is point the data service at the data model to be exposed as a REST-service and we’ll be set. The snippet below shows the 2 or so lines of code you need to write to do this. One thing to note is that a data service is locked down by default, so we need to take explicit steps to open access to it. For this simple application we’ll enable read and write access to the entire model quickly using the call to ‘SetEntitySetAccessRule’ shown below.
That’s it, our data service is now created. To test this, run the project and navigate to the nw.svc file. You should see a listing as shown below that outlines all the entry points to the data service. If you don’t, tweak your IE settings and reload.
Step 3: Set Server Driven Paging Limits
At this point we have a working data service and are ready to configure the Server Driven Paging limits for the service. For example, to limit the number of Customer entities the data service will return per request to 4, we would add the following call to 'SetResourceSetPageSize' to our data service:
If you view the nw.svc file in the browser and navigate to the nw.svc/Customers endpoint of the service you should now only see four customer entities returned even though the Northwind DB has many more than four customers in it.
The next thing to notice is the response from the data service includes a "next link" which is a URI indicating how a client can continue retrieving the rest of the entities in the collection not returned by the first request. The images below show the AtomPub and JSON representations returned (and the associated "next links") when querying the nw.svc/Customers URI.
Sending an HTTP GET request to the "next link" in the above listing would allow the client to continue making progress towards obtaining the entire set of Customer entities. In this example a GET request sent to the URI nw.svc/Customers?$skiptoken='AROUT' would retrieve the next four Customers (sorted by key) from the data service after those in the above listing.
This feature works in conjunction with all query requests (arbitrary filters, result ordering, etc). For example, if a GET request is sent to the URI: nw.svc/Customers?$filter=City eq 'London'&$orderby=PostalCode , the results returned will be the first four Customers in London sorted by PostalCode and the "next link" returned will be equal to: nw.svc/Customers?$filter=City eq 'London'&$orderby=PostalCode&$skiptoken='WA1 1DP','AROUT'.
It is important to note this feature is a server driven paging mechanism which allows a data service to gracefully return partial sets to a client. If a client application knows it wants a subset of the total number of entities in an entity set (perhaps to bind to a paged grid UI control) then it should use the client driven paging query string options ($top and $skip) available starting with the v1 data services framework. For additional information on $top and $skip see this "Using ADO.NET Data Services" (v1) whitepaper.
Providing Feedback
We have created a new forum dedicated to providing feedback on "pre-release" versions of data services such as this CTP. Please direct all your questions and comments about this feature to this new forum which is available at: (http://social.msdn.microsoft.com/Forums/en-US/dataservices/threads).
Note: The forum intended for questions on currently shipping versions of ADO.NET Data Services is still available at: (http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/threads/ )
We look forward to hearing your feedback.
-Mike Flasko
ADO.NET Data Services, Program Manager
-
Peter Qian, a developer on the data services team, has posted a nice write up describing the row count feature in the ADO.NET Data Services v1.5 CTP1 release we made available for download yesterday.
You can check out Peter's Row Count write up here.
Also, we have created a new forum dedicated to providing feedback on "pre-release" versions of data services such as this CTP. Please direct all questions and comments about this feature to this new forum which is available at: (http://social.msdn.microsoft.com/Forums/en-US/dataservices/threads).
We look forward to hearing your feedback.
-Mike Flasko
ADO.NET Data Services, Program Manager
-
Two weeks ago we announced the ADO.NET Data Services v1.5 release. Today we're very happy to say CTP1 of ADO.NET Data Services v1.5 is now available for download. You can get the bits by clicking here.
This first CTP release is intended to allow exploration, prototyping and early development. It is not supported and is not for use on production systems.
Getting Started
To get started with the v1.5 CTP1 bits, check out the"getting started" video below. The video walks through what is provided in CTP1 and how to get a simple project up and running quickly.
Upgrading an Existing Project to Use v1.5 CTP1
To upgrade an existing server-side data service project to use this CTP you'll need to replace all System.Data.Services.* assembly references with Microsoft.Data.Services.* references. Next edit the markup of the .svc file for the existing data service to point at the Microsoft.Data.Services.dll assembly. At this point, rebuild the project and your done -- the project is now upgraded to use this CTP.
If you have an existing client project, the easiest way to upgrade existing service references is to delete the reference and then re-add it following the steps outline in the video above.
What's Included in this CTP?
For an overview of the new features in this first CTP, see our prior post announcing the v1.5 release. In addition, we will create feature-specific blog posts over the coming days to explain each feature in more detail.
CTP1 Frequently Asked Questions
Q1: What are the prerequisites?
A1: See the CTP download center page here for a list of prerequisites, supported operating systems, etc?
Q2: Does CTP1 install side-by-side with what is currently on my development machine?
A2: By in large this install is side-by-side with existing VS 2008 SP1 and .NET Fx 3.5SP1 bits; however, that was not possible in all cases so some .NET and VS files will be modified by the CTP1 installer. The files should be replaced to their original state during uninstall of this CTP.
Q3: Does this CTP work on Windows 7?
A3: The CTP1 installer will install the runtime components only on Windows 7. Client code generation is not yet enabled by the CTP1 installer on Windows 7.
Giving Feedback
We have created a new forum dedicated to providing feedback on "pre-release" versions of data services such as this CTP. Please direct all your questions about the release and its features to this forum which is available at: (http://social.msdn.microsoft.com/Forums/en-US/dataservices/threads).
Note: The forum intended for questions on currently shipping versions of ADO.NET Data Services is still available at: (http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/threads/ )
We look forward to hearing your thoughts on the release!
-Mike Flasko
ADO.NET Data Services, Program Manager
-
In October of last year we started to talk publicly about an exploration project we called “Astoria Offline”, we showed a working version of it at PDC 2008 and we said we would ship the experimental bits as soon as we could.
It ended up taking us longer than we thought to get a shipping package in reasonable shape (i.e. we had to clean up the bits, add docs/samples, etc). This delay was mostly because we were busy building the next version of the real product (the ADO.NET Data Services framework) we announced a few days ago.
I’m happy to announce that we finally posted the “Astoria Offline” bits in the download center. You can find the installer and readme here:
http://www.microsoft.com/downloads/details.aspx?FamilyID=479f2216-e6f2-486f-80c9-2cfade5082c1&displaylang=en
The installer includes a document that will guide you step-by-step through a first “Astoria Offline” application. If you’d like to hear “the pitch” that includes some context and an end-to-end demo, you can watch the PDC talk where we first discussed this project:
http://channel9.msdn.com/pdc2008/TL08/
You just announced v1.5 CTP, what’s the relationship between these things?
I think it’s worth it describing how this alpha release relates to the ADO.NET Data Services v1.5 CTP we announced last week.
The v1.5 CTP represents the current state of the next version of ADO.NET Data Services. Modulo any features that may come and go, it will become the next official release that you’ll be able to use to create production solutions.
At the same time, while we build the next version, we continue to explore the space of data services and its ties to other technologies to provide value-added solutions. One of these exploration exercises is “Astoria Offline”. Only a few of these exploration exercises end up becoming products and even those that do usually are transformed a lot between the early days (where “Astoria Offline” is now) and their final form.
Frequently Asked Questions
Q: How solid is this preview?
A: Not at all :). This is an experimental release with the goal of engaging with our developer community and discussing the topic.
Q: Can I start building an application based on this preview, and then expect to able to port it to future versions?
A: We would recommend against that. This preview is better suited for experiments and prototyping. Future releases will most likely heavily differ from this one in many aspects as we learn lessons and as we receive and apply feedback from developers trying it out.
Q: Can I use this preview in a production application?
A: No, this release may not be used in production environments
Q: Do you know when are you going to ship another update?
A: We have no planned dates for an update at this time. We are currently heads down working on other near-term deliverables to address common requests from ADO.NET Data Services framework customers. Where go from here largely depends on your feedback, and may include significant changes in direction based on that feedback.
Q: Is this technology going to be present in the next version of ADO.NET Data Services and/or Visual Studio?
A: No. We are working on two fronts. One is the enhancements we want to make to the ADO.NET Data Services framework in the next release. The other is about long-term direction and exploration. Project Codename "Astoria Offline" falls into the second category.
Q: Where can I ask questions and send suggestions about this preview?
A: The best places are the Astoria Team Blog (http://blogs.msdn.com/astoriateam) and the ADO.NET Data Services forums (http://social.msdn.microsoft.com/Forums/en-US/dataservices/threads)
Q: Should I install this in my main computer? Will it affect other components?
A: While we made an effort to minimize the impact of this preview on what you already have installed, the install is not completely isolated. In particular, we renamed most assemblies that we modified so they would install side-by-side with the originals. However, that wasn't possible for all of them. On the same lines, we tried not to update existing registry entries but we're forced to do it for some settings. Bottom line is that we recommend that you try this preview in a test system, or in a Virtual PC so it doesn't interfere with your main system.
Q: I see that all the documentation and example focus on desktop applications. How about Silverlight? How about mobile devices?
A: This first round is focused on desktop applications as that was a more clearly-understood scenario. As we continue to look at the space we’ll certainly think about these other scenarios as well.
Q: The current bits use SQL Server Express as the local database on the client. Have you considered SQL Server Compact Edition?
A: Yes, definitely. We would have done support for both if we had had the time. For this first round we had to choose one, and SQL Server Express was an easier choice just because we could reuse infrastructure between client and server.
Looking forward to hear your thoughts.
Pablo Castro
Software Architect
-
It's been a little while since we've written about the future direction of data services, so this post is intended to layout our thinking towards our next release. The release described below isn't yet available, but should be in the coming months, so stay tuned :). The rest of this post will discuss the specifics of the release being announced and what to expect in terms of features in CTP1.
ADO.NET Data Services v1.5 CTP1 is a tech preview of the next release of ADO.NET Data Services. This release (v1.5) will target the .NET Framework 3.5 SP1 & Silverlight 2 platforms and provide new client and server side features for data service developers.
Why is v1.5 in the name?
V1 = The release of the ADO.NET Data Services runtime and client libraries included in the .NET Framework 3.5 SP1 and Silverlight 2
V1.5 (this release) = A standalone web release which includes a superset of the functionality shipped in V1.
How does this release relate to ADO.NET Data Services as shipped in the .NET Framework 3.5 SP1?
This release (v1.5 CTP1) is a standalone release and represents our in progress work towards the next version of the ADO.NET Data Service technology we shipped in the .NET Framework 3.5 SP1. Since this is a standalone release, it will NOT be an in-place update of the v1 assemblies (System.Data.Services.*.dll) in the .NET Framework 3.5 SP1. Instead, this release will coexist with v1, allowing you the choice of building applications against either release. Like v1, this release also targets the .NET Framework 3.5 SP1 so we can quickly iterate on a feature set which makes it easier to use data services in cloud services (e.g. Windows Azure Table Storage, etc) and to address the needs of web-focused applications which iterate on a relatively short cycle.
How does this release relate to Silverlight 2?
This release (v1.5 CTP1) will include an updated client library for consuming data services from Silverlight 2. The additional features included are described in the feature list below.
How does this release relate to the next release of the .NET Framework (ie. .NET Framework 4.0)?
As noted above, ADO.NET Data Services v1.5 will initially target the .NET Framework 3.5 SP1 and Silverlight 2 platforms and will likely be released prior to the .NET Framework 4.0 platform. A future version of this standalone release (v1.5) will be created to support the .NET Framework 4.0 platform.
When will v1.5 CTP1 ship?
We aren't yet ready to announce a release date, but we are in the close down phase of the feature set for CTP1, so we are hoping to have more to say here in the not too distant future :).
What's coming in CTP1?
ADO.NET Data Services v1.5 CTP1 will include the following enhancements and features:
Data Binding: The data services client library for the .NET Framework 3.5 SP1 and Silverlight2 has been extended to support two-way data binding for WPF and Silverlight based applications.
Row Count: One scenario we heard a ton of feedback on after shipping V1 of ADO.NET Data Services in the .NET Framework 3.5SP1 is the ability for the a client of a data service to determine the total number of entities in a set without having to retrieve them all. To address this need, we have extended the data services addressing scheme to allow a client to obtain this type of information without having to download all the entities in a set.
Feed Customization (aka "Web Friendly Feeds"): A common ask we have received is to provide the ability to customize how entities are mapped into the various elements of an AtomPub feed. This feature does just that by providing a data service author declarative control over how the data service runtime maps the properties of an entity (e.g. a Customer, Order, etc) to the elements of a feed.
Server Driven Paging: This one is best described by example. If you had a data service that exposes photos, you likely want to limit the total number of photos a single request to the service can retrieve because the total collection of photos may be very large. This feature allows a service author to set per collection limits on the total number of entities returned for each request. In addition to limiting the number of photos returned per request, the server provides the client a "next link" which is simply a URI specifying how to continue retrieving the rest of the entities in the collection not returned by the first request. For those familiar with AtomPub, this feature adds support for AtomPub <next ..> elements to the data service runtime. For CTP1 we'll include server side support for this feature only. Client library support will likely come in a future CTP.
Enhanced BLOB Support: This feature enhances the BLOB support provided in V1 to enable data services to stream arbitrarily large BLOBs, store binary content separate from its metadata, easily defer the loading of BLOB content when its metadata is requested, etc. For CTP1 we'll include server side support for this feature only. Client library support will likely come in a future CTP.
New "Data Service Provider" Interface for Custom Provider Writers: As the data services runtime has evolved, so has the number of ways people want to plug data into the data service framework. In V1, two methods (Entity Framework and arbitrary .NET classes) were supported to enable a data service to interact with various diverse data sources. To address another class of environments and data sources we have introduced a way to write a "custom" provider for those cases when the previous two provider models don't meet your needs.
Bug Fixes: This release builds on our existing (v1) code base and will incorporate all fixes we have made to this point.
We've already discussed some of the features above in our transparent design process notes on this blog (example: here and here). This CTP release represents our take at addressing these areas, so when the release becomes available, please give these features a spin and let us know what you think.
As we get closer to having the CTP1 bits ready to make available on the download center, we'll post additional documentation, samples, etc. as "getting started" material for the features.
-Mike Flasko
ADO.NET Data Services Program Manager
-
Beth Massi has been busy creating a number of great posts describing how to build add-ins to Excel, Outlook, Word, etc to work with data from an ADO.NET Data Service. The articles can be found here:
ADO.NET Data Services - Building an Excel Client
OBA Part 1 - Exposing Line-of-Business Data
OBA Part 2 - Building an Outlook Client against LOB Data
OBA Part 3 - Storing and Reading Data in Word Documents
Also, Beth graciously offered to convert the code samples from the current "Using ADO.NET Data Services" whitepaper to VB as they are currently only available in C#. We're working on getting the VB snippets integrated into the document, but for now they are also available here.
-Mike Flasko
ADO.NET Data Services, Program Manager
-
Believe it or not, but we did ship ADO.NET Data Services with a few bugs. One issue in particular is fairly nasty. However the code developers might be tempted to write to work around the bug could cause far worse problems down the road when we fix the initial bug. Hence I wanted to give a quick write up to describe the issue and give a quick sample of how to write code that will work now and in the future when we fix the issue.
The problem exists in the ADO.NET Data Services client (System.Data.Services.Client.dll) we shipped with .NET 3.5 sp1 and Silverlight 2.0 SDK. In particular, we do not throw the correct exception when a HTTP request has problems while being sent to the server. I.e. a request timeouts, there is a bad server name, etc. In other words, any problem that would normally raise a System.Net.WebException. Unfortunately, in V1 of ADO.NET Data Services a NullReferenceException is raised instead of a WebException and even worse, the exception message is lost:
DataServiceContext context =
new DataServiceContext(
new Uri("http://BadServer/Northwind.svc"));
// Set small timeout amount to intentionally timeout request context.Timeout = 1;
DataServiceQuery<Customer> query =
context.CreateQuery<Customer>("Customers");
try
{
foreach (Customer c in query) { }
}
catch (NullReferenceException nre)
{
// in V1, NullReferenceException is //thrown instead of WebException.
// Also, no useful description
Console.WriteLine("Something bad happened!");
}
We are planning on fixing this bug in a future version of ADO.NET Data Services client (both in .NET and Silverlight) so if your code relies exclusively on catching the NullReference exception, it will be broken when we ship the fix. Hence, to make your code robust – have your code explicitly catch both exception types:
DataServiceContext context =
new DataServiceContext(
new Uri("http://BadServer/Northwind.svc"));
// Set small timeout amount to intentionally timeout request context.Timeout = 1;
DataServiceQuery<Customer> query =
context.CreateQuery<Customer>("Customers");
try
{
foreach (Customer c in query) { }
}
catch (WebException e)
{
// When fix is shippped, will ADO.NET Data Services // will correctly throw webException
Console.WriteLine(e.Message);
}
catch (NullReferenceException nre)
{
// in V1, NullReferenceException is thrown // instead of WebException.
// Also, no useful description
Console.WriteLine("Something bad happened!");
}
We will update the team blog when we have a better idea of when the fix will be available. All I can say now is we are looking into trying to get it out sooner than later, but we hope to have more information on this in the near future.
Andrew Conrad
ADO.NET Data Services Development Lead.
-
One of the scenarios we have heard feedback around is the ability for the a client of a data service to determine the total number of entities in a set without having to retrieve them all. The following video discusses this scenario in more detail and some of our thoughts regarding how to make the experience better.
Astoria Design Walkthrough: Introducing $count as an URI query option
Additional design details:
- The count value would be calculated after $filter expressions are applied. For example /Customers?$filter=City eq 'London' would return a count value made up of only the customers living in London and not all the customers.
- If a query included $top, $skip or $orderby, the count value would be unaffected. For example /Customers?$top=1&$skip=2&$orderby=Name would return the total number of customers stored by the service.
- If a query includes a $expand, then the count applies to the outer entity set. For example /Customers?$expand=Orders would return the number of customers stored by the service
What do you think? Would this be useful in your data services applications?
Mike Flasko
ADO.NET Data Services, Program Manager
This post is part of the transparent design exercise in the Astoria Team. To understand how it works and how your feedback will be used please look at this post.