<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://mobileworld.appamundi.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Andy Wigley : REST, TechEd</title><link>http://mobileworld.appamundi.com/blogs/andywigley/archive/tags/REST/TechEd/default.aspx</link><description>Tags: REST, TechEd</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 (Build: 30912.2823)</generator><item><title>Accessing RESTful 'Astoria' Data Services in .NET Compact Framework</title><link>http://mobileworld.appamundi.com/blogs/andywigley/archive/2008/11/24/accessing-restful-astoria-data-services-in-net-compact-framework.aspx</link><pubDate>Mon, 24 Nov 2008 17:17:00 GMT</pubDate><guid isPermaLink="false">989b12f5-6f26-47d9-9f0d-67fe982b88db:28</guid><dc:creator>Andy Wigley</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://mobileworld.appamundi.com/blogs/andywigley/rsscomments.aspx?PostID=28</wfw:commentRss><comments>http://mobileworld.appamundi.com/blogs/andywigley/archive/2008/11/24/accessing-restful-astoria-data-services-in-net-compact-framework.aspx#comments</comments><description>&lt;p&gt;In my recent presentation at Microsoft Tech Ed EMEA 2008 in Barcelona (session MBL304), I talked about how to access RESTful web services from the .NET Compact Framework. I promised that I would post the sample code on my blog, so this post is to fulfil that promise, and also to explain how to do this for those who weren&amp;#39;t in Barcelona. I also used this sample as an example of how to use HttpWebRequest in my recent webcast on Networking, so this post is also relevant to that webcast.&lt;/p&gt;
&lt;h2&gt;What is a RESTful Data Service?&lt;/h2&gt;
&lt;p&gt;REST stands for &amp;#39;&lt;strong&gt;RE&lt;/strong&gt;presentational &lt;strong&gt;S&lt;/strong&gt;tate &lt;strong&gt;T&lt;/strong&gt;ransfer&amp;#39; and is a technique for exposing data over the web in a lightweight manner that is suitable for accessing programmatically using simple HTTP GET, PUT, POST and DELETE verbs. The actual resource that you wish to get/delete/update/create is identified by the uri of the request. For example, if you have a data service that exposes the data of the Northwind database, to get a list of the top-level collections in the data service (maps to the tables or views in the Northwind database), you might issue an HTTP GET to &lt;span style="text-decoration:underline;"&gt;http://myserver/myNorthwindDataService/Northwind.svc&lt;/span&gt; and you&amp;#39;ll get back a bunch of XML. To get a list of all the Customers in Northwind, you issue a GET to &lt;span style="text-decoration:underline;"&gt;http://myserver/myNorthwindDataService/Northwind.svc/Customers&lt;/span&gt; and if you want a specific customer record, you can put the primary key in the URI like this: &lt;span style="text-decoration:underline;"&gt;http://myserver/myNorthwindDataService/Northwind.svc/Customers(&amp;#39;ALFKI&amp;#39;)&lt;/span&gt; which returns all the data for that customer record as XML:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://mobileworld.appamundi.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/andywigley/ADO.NET-Data-Services.jpg" alt="" /&gt;&lt;/p&gt;
&lt;h2&gt;Creating an ADO.NET Data Services website&lt;/h2&gt;
&lt;p&gt;To create a site that exposes the Northwind database in this way, you need Visual Studio 2008 SP1 and the Northwind database installed in SQL Server 2005/2008&amp;nbsp;- I&amp;#39;ve included a script to create the Northwind database in the download accompanying this post. Follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a new ASP.NET Website project called &lt;strong&gt;DataServicesWebsite&lt;/strong&gt; - this&amp;nbsp;should be hosted in IIS not the file System to allow devices to access it.&lt;/li&gt;
&lt;li&gt;Delete Default.aspx as we&amp;#39;ll be generating our own service&lt;/li&gt;
&lt;li&gt;In Solution Explorer, right-click on the website root and then click &lt;strong&gt;Add New Item&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;In the Templates window, select &lt;strong&gt;ADO.NET Entity Data Model&lt;/strong&gt;, and in the Name field, enter &lt;strong&gt;NorthwindModel.edmx&lt;/strong&gt;. Click &lt;strong&gt;Add&lt;/strong&gt;. Click &lt;strong&gt;Yes&lt;/strong&gt; to the &amp;#39;You are attempting to add a special file type...&amp;#39; pop-up.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Entity Data Model&lt;/strong&gt; window, select &lt;strong&gt;Generate from database&lt;/strong&gt; and click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;New Connection&lt;/strong&gt; to make a connection to the SQL Server where you have Northwind installed, and when you have that setup click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Choose Your Database Objects&lt;/strong&gt; window, click the checkbox to select all the Tables, then click &lt;strong&gt;Finish&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You should now see the entity data model diagram - this model will provide the source for our data services website.&lt;/li&gt;
&lt;li&gt;Right-click on the website root in Solution Explorer and then click &lt;strong&gt;Add New Item&lt;/strong&gt;. Select &lt;strong&gt;ADO.NET Data Service&lt;/strong&gt; on the Templates window, and then click &lt;strong&gt;Add&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You will now see a code editor window with the source of a class called &lt;strong&gt;WebDataService&lt;/strong&gt;, which has a couple of TODOs in it. First you&amp;#39;ll see that WebDataService inherits from a generic class: &lt;strong&gt;DataService&amp;lt; /* TODO: put your data source class name here */&amp;gt;&lt;/strong&gt; - replace that TODO with the name of the data source class, which is &lt;strong&gt;NorthwindModel.NorthwindEntities&lt;/strong&gt;. Then inside the &lt;strong&gt;InitializeService&lt;/strong&gt; method, you need to set some access rules, which you can do easily by uncommenting the suggested lines and replacing the first parameter of each with a wildcard character. After this, the class should look like this:&lt;br /&gt;&lt;br /&gt;public class WebDataService : DataService&amp;lt; NorthwindModel.NorthwindEntities &amp;gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // This method is called only once to initialize service-wide policies.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void InitializeService(IDataServiceConfiguration config)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; config.SetEntitySetAccessRule(&amp;quot;*&amp;quot;, EntitySetRights.AllRead);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; config.SetServiceOperationAccessRule(&amp;quot;*&amp;quot;, ServiceOperationRights.All);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;That&amp;#39;s it! Now just right-click on &lt;strong&gt;WebDataService.svc&lt;/strong&gt; in Solution Explorer, and click &lt;strong&gt;Set as Start Page&lt;/strong&gt;. Now you can&amp;nbsp;hit &lt;strong&gt;CTRL-F5&lt;/strong&gt; to run&amp;nbsp;the site to check it works - you&amp;#39;ll be able to fetch data from the database just by using a browser window. Try adding &amp;#39;/Customers&amp;#39; or &amp;#39;/Products&amp;#39; to the starting address in the browser window to see how it works.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;&amp;nbsp;Creating a .NET Compact Framework Client&lt;/h2&gt;
&lt;p&gt;If you are lucky enough to be a desktop or Silverlight developer, then the ADO.NET Data Services team have created a client-side library for you to use called System.Data.Services.Client, but for some unfathomable reason, they didn&amp;#39;t create this library for .NETCF. That library gives you what is sometimes known as &amp;#39;LINQ to URI&amp;#39;, as it translates LINQ queries into the required HTTP calls to fetch the data. So if you want to know how to use that library from a desktop or Silverlight client, you can look at &lt;a target="_blank" href="http://blogs.microsoft.co.il/blogs/bursteg/archive/2008/05/12/visual-studio-2008-sp1-querying-ado-net-data-service-net-client.aspx" title="this blog"&gt;this blog&lt;/a&gt;&amp;nbsp;from Guy Burstein.&lt;/p&gt;
&lt;p&gt;However, we mobile devs must do it the hard way - which actually is not so hard if we use some simple calls using HttpWebRequest and HttpWebResponse to fetch the XML, and a little bit of LINQ to XML to extract the data we want from the response.&lt;/p&gt;
&lt;p&gt;First, we need to get the XML from the service. We can use a couple of utility methods to do this. Here&amp;#39;s the entire class containing both methods:&lt;/p&gt;
&lt;p&gt;using System;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Net;&lt;br /&gt;using System.IO;&lt;/p&gt;
&lt;p&gt;namespace RESTLibrary&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public enum HttpMethods { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GET = 0, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PUT, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; POST, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DELETE, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HEAD, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; OPTIONS, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LIST, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UNKNOWN }&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class REST&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static HttpWebRequest CreateRequest(string uri, HttpMethods method, string data, string contentType, string userName, string password)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WebRequest request = HttpWebRequest.Create(uri);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.Method = Enum.ToObject(typeof(HttpMethods), method).ToString();&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.Credentials = &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new NetworkCredential(userName, password);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.ContentType = contentType;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((HttpWebRequest)request).Accept = contentType;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (method != HttpMethods.GET &amp;amp;&amp;amp; method != HttpMethods.DELETE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Encoding encoding = Encoding.UTF8;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.ContentLength = encoding.GetByteCount(data);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.ContentType = contentType;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.GetRequestStream().Write(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; encoding.GetBytes(data), 0, (int)request.ContentLength);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.GetRequestStream().Close();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // If we&amp;#39;re doing a GET or DELETE don&amp;#39;t bother with this &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request.ContentLength = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Finally, return the newly created request to the caller. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return request as HttpWebRequest;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static string ReadResponse(HttpWebResponse response)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Read the contents to a string &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // and return that to the caller. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string responseBody = String.Empty;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (Stream stm = response.GetResponseStream())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (StreamReader reader = new StreamReader(stm))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Simply read in the entire response to our string. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; responseBody = reader.ReadToEnd();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; reader.Close();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return responseBody;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;The first of these methods, &lt;strong&gt;CreateRequest&lt;/strong&gt;, creates an HttpWebRequest instance properly configured to make the call to fetch the data. The second utility method, &lt;strong&gt;ReadResponse&lt;/strong&gt;, reads the string that is sent back from the web data service and returns it to the caller. The client code to use these looks like this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Create the request object using the utility method &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // This code accesses host ppp_peer so the device must be connected to the server by ActiveSync.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpWebRequest request = REST.CreateRequest(@&amp;quot;&lt;a href="http://ppp_peer/DataServicesWebsite/NorthwindService.svc/Customers"&gt;http://ppp_peer/DataServicesWebsite/NorthwindService.svc/Customers&lt;/a&gt;&amp;quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpMethods.GET, String.Empty, @&amp;quot;application/atom+xml&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;); &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Now, attempt to read in the data. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string responseXml = REST.ReadResponse(response);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Do something with the response XML&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;All that remains is to extract the data we want from the XML. If you haven&amp;#39;t used LINQ to XML much, here is the important stuff you need to know. &lt;/p&gt;
&lt;p&gt;Let&amp;#39;s say we want to extract the CustomerID, CompanyName and City of every customer in the Customers collection. If you use a browser to look at the XML returned for the Customers collection, you&amp;#39;ll see that the elements we want are all children of the properties tag:&lt;/p&gt;
&lt;p&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; standalone=&amp;quot;yes&amp;quot; ?&amp;gt;&lt;br /&gt;- &amp;lt;feed xml:base=&amp;quot;&lt;a href="http://localhost/DataServicesWebsite/NorthwindService.svc/"&gt;http://localhost/DataServicesWebsite/NorthwindService.svc/&lt;/a&gt;&amp;quot; xmlns:d=&amp;quot;&lt;a href="http://schemas.microsoft.com/ado/2007/08/dataservices"&gt;http://schemas.microsoft.com/ado/2007/08/dataservices&lt;/a&gt;&amp;quot; xmlns:m=&amp;quot;&lt;a href="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"&gt;http://schemas.microsoft.com/ado/2007/08/dataservices/metadata&lt;/a&gt;&amp;quot; xmlns=&amp;quot;&lt;a href="http://www.w3.org/2005/Atom"&gt;http://www.w3.org/2005/Atom&lt;/a&gt;&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;title type=&amp;quot;text&amp;quot;&amp;gt;Customers&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;id&amp;gt;http://localhost/DataServicesWebsite/NorthwindService.svc/Customers&amp;lt;/id&amp;gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;... &lt;br /&gt;- &amp;lt;content type=&amp;quot;application/xml&amp;quot;&amp;gt;&lt;br /&gt;- &lt;strong&gt;&amp;lt;m:properties&amp;gt;&lt;/strong&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;strong&gt;&amp;lt;d:CustomerID&amp;gt;ALFKI&amp;lt;/d:CustomerID&amp;gt;&lt;/strong&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&amp;lt;d:CompanyName&amp;gt;Alfreds Futterkiste&amp;lt;/d:CompanyName&amp;gt;&lt;/strong&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;d:ContactName&amp;gt;Maria Anders&amp;lt;/d:ContactName&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;d:ContactTitle&amp;gt;Sales Representative&amp;lt;/d:ContactTitle&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;d:Address&amp;gt;Obere Str. 57&amp;lt;/d:Address&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&amp;lt;d:City&amp;gt;Berlin&amp;lt;/d:City&amp;gt;&lt;/strong&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;d:Region m:null=&amp;quot;true&amp;quot; /&amp;gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;lt;/m:properties&amp;gt;&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;m:&lt;/strong&gt; prefix to the properties tag, and the &lt;strong&gt;d:&lt;/strong&gt; prefix to the individual fields tags are important - they indicate that the tag belongs in a particular XML namespace. The &amp;#39;d&amp;#39; and &amp;#39;m&amp;#39; are both symbols for namespaces, which are defined at the top of the XML in the &lt;strong&gt;&amp;lt;feed&amp;gt;&lt;/strong&gt; element:&lt;/p&gt;
&lt;p&gt;- &amp;lt;feed xml:base=&amp;quot;&lt;a href="http://localhost/DataServicesWebsite/NorthwindService.svc/"&gt;http://localhost/DataServicesWebsite/NorthwindService.svc/&lt;/a&gt;&amp;quot; xmlns:&lt;strong&gt;d&lt;/strong&gt;=&amp;quot;&lt;a href="http://schemas.microsoft.com/ado/2007/08/dataservices"&gt;http://schemas.microsoft.com/ado/2007/08/dataservices&lt;/a&gt;&amp;quot; xmlns:&lt;strong&gt;m&lt;/strong&gt;=&amp;quot;&lt;a href="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"&gt;http://schemas.microsoft.com/ado/2007/08/dataservices/metadata&lt;/a&gt;&amp;quot; xmlns=&amp;quot;&lt;a href="http://www.w3.org/2005/Atom"&gt;http://www.w3.org/2005/Atom&lt;/a&gt;&amp;quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;Tags that do not have a prefix are in the &lt;em&gt;default&lt;/em&gt; namespace, which is the one specified in the &amp;lt;feed&amp;gt; element that does not have prefix, which is the last one listed, &lt;strong&gt;xmlns=&lt;/strong&gt;&lt;a href="http://www.w3.org/2005/Atom"&gt;&lt;strong&gt;http://www.w3.org/2005/Atom&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once you understand the definition of the namespaces, the LINQ to XML query to select the required customer properties from every record in the Customers collection becomes the following. This example not only selects the target fields, but uses the values to initialise a new instance of a &lt;em&gt;CustLite&lt;/em&gt; object, which is a custom class defined for this example that just has three public properties, &lt;strong&gt;CustomerID&lt;/strong&gt;, &lt;strong&gt;CompanyName&lt;/strong&gt; and &lt;strong&gt;City&lt;/strong&gt;. As a result, the type of the customerIdList, defined as &lt;em&gt;var&lt;/em&gt; in the code, is actually a List&amp;lt;CustLite&amp;gt;:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // After reading in the response parse the response into a XDocument. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; XDocument customerDoc = XDocument.Parse(responseXml);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; XNamespace ads = @&amp;quot;&lt;a href="http://schemas.microsoft.com/ado/2007/08/dataservices"&gt;http://schemas.microsoft.com/ado/2007/08/dataservices&lt;/a&gt;&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; XNamespace m = @&amp;quot;&lt;a href="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"&gt;http://schemas.microsoft.com/ado/2007/08/dataservices/metadata&lt;/a&gt;&amp;quot;;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var customerIdList =&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from c in customerDoc.Descendants(m + &amp;quot;properties&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new CustLite()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CustomerID = c.Element(ads + &amp;quot;CustomerID&amp;quot;).Value,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CompanyName = c.Element(ads + &amp;quot;CompanyName&amp;quot;).Value,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; City = c.Element(ads + &amp;quot;City&amp;quot;).Value,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/p&gt;
&lt;p&gt;Once we have our List&amp;lt;CustLite&amp;gt; we can use it in our app, for example to display it in a DataGrid:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="http://mobileworld.appamundi.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/andywigley/CustLite-Display.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You can download the code for the sample from the link below. Note that this example shows how to get data formatted using the ATOM MPP XML format, but ADO.NET Data Services also returns data in JSON if you ask it right - that&amp;#39;s the subject for another post...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://mobileworld.appamundi.com/aggbug.aspx?PostID=28" width="1" height="1"&gt;</description><enclosure url="http://mobileworld.appamundi.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.00.28/REST-Sample.zip" length="24235" type="application/x-zip-compressed" /><category domain="http://mobileworld.appamundi.com/blogs/andywigley/archive/tags/TechEd/default.aspx">TechEd</category><category domain="http://mobileworld.appamundi.com/blogs/andywigley/archive/tags/Webcast/default.aspx">Webcast</category><category domain="http://mobileworld.appamundi.com/blogs/andywigley/archive/tags/MSDN/default.aspx">MSDN</category><category domain="http://mobileworld.appamundi.com/blogs/andywigley/archive/tags/Networking/default.aspx">Networking</category><category domain="http://mobileworld.appamundi.com/blogs/andywigley/archive/tags/Astoria/default.aspx">Astoria</category><category domain="http://mobileworld.appamundi.com/blogs/andywigley/archive/tags/REST/default.aspx">REST</category></item></channel></rss>