Hello all , with the recent release of ADO.NET Data v1.5 Services CTP 1 , we introduced a new feature called as “Web Friendly Feeds”. With the release of CTP2 , we have introduced support for 2 additional ATOM:Entry elements you can map to:
What is this feature about ?
This is what the markup for one of the the resources of Customers looks like in ADO.NET Data Services v1 .
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <entry xml:base=http://localhost:26503/northwind.svc/ xmlns:d=http://schemas.microsoft.com/ado/2007/08/dataservices xmlns:m=http://schemas.microsoft.com/ado/2007/08/dataservices/metadata xmlns="http://www.w3.org/2005/Atom"> <id>http://localhost:26503/northwind.svc/Customers('ALFKI')</id> <title type="text" /> <updated>2009-03-18T20:30:20Z</updated> <author> <name /> </author> <category term="NorthwindModel.Customers" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <content type="application/xml"> <m:properties> <d:CustomerID>ALFKI</d:CustomerID> <d:CompanyName>Alfreds Futterkiste</d:CompanyName> <d:ContactName>Maria Anders</d:ContactName> <d:ContactTitle>Sales Representative</d:ContactTitle> <d:Address>Obere Str. 57</d:Address> <d:City>Berlin</d:City> <d:Region m:null="true" /> <d:PostalCode>12209</d:PostalCode> <d:Country>Germany</d:Country> <d:Phone>030-0074321</d:Phone> <d:Fax>030-0076545</d:Fax> </m:properties> </content> </entry>
In the markup above , a couple of things are missing
1) The <title> element is empty
<title type="text" />
2) The author/name element is empty
<author> <name /> </author>
Now , let’s say that we wanted to map the “ContactName” as the author name element of the entry element and Title to be “ContactTitle” as the title of the entry element. Then , the payload would look like this :
<entry > <id>http://localhost:26503/northwind.svc/Customers('ALFKI')</id> <title type="text">Sales Representative</title> <updated>2009-03-18T20:46:42Z</updated> <author> <name>Maria Anders</name> </author> <category term="NorthwindModel.Customers" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <content type="application/xml"> <m:properties> <d:CustomerID>ALFKI</d:CustomerID> <d:CompanyName>Alfreds Futterkiste</d:CompanyName> <d:ContactName>Maria Anders</d:ContactName> <d:ContactTitle>Sales Representative</d:ContactTitle> <d:Address>Obere Str. 57</d:Address> <d:City>Berlin</d:City> <d:Region m:null="true" /> <d:PostalCode>12209</d:PostalCode> <d:Country>Germany</d:Country> <d:Phone>030-0074321</d:Phone> <d:Fax>030-0076545</d:Fax> </m:properties> </content> </entry>
This also means , that IE now displays the Title & author Name elements when you browse to the “Customers” entity set .
Which elements in the atom:entry element can I map to an entity type properties ?
Once a property is mapped , if keeping the value of the property in the entry:contents section doesn’t make sense,can I remove it ? Yes , absolutely , in the above case , we can remove the ContactName & ContactTitle elements from being repeated in the <contents> section. Ex:
<entry> <id>http://localhost:26503/northwind.svc/Customers('ALFKI')</id> <title type="text">Sales Representative</title> <updated>2009-03-18T21:04:20Z</updated> <author> <name>Maria Anders</name> </author> <category term="NorthwindModel.Customers" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <content type="application/xml"> <m:properties> <d:CustomerID>ALFKI</d:CustomerID> <d:CompanyName>Alfreds Futterkiste</d:CompanyName> <d:Address>Obere Str. 57</d:Address> <d:City>Berlin</d:City> <d:Region m:null="true" /> <d:PostalCode>12209</d:PostalCode> <d:Country>Germany</d:Country> <d:Phone>030-0074321</d:Phone> <d:Fax>030-0076545</d:Fax> </m:properties> </content> </entry>
Great , what else can I do with this new feature ? Well, did I mention you can embed your own markup in the <entry> element for an entity type !!!
consider the following entity type , BlogPost , which looks like this
public class BlogPost { public double Lat { get; set; } public double Long { get; set; } public int BlogPostID { get; set; } public string Title { get; set; } public string Body { get; set; } public string Author { get; set; } public string PostURI { get; set; } public string ContentSummary{get;set;} }
This type represents the entry for a blog post , and also contains the Geographical location information about where the post was made ( Lat /Long) and also the author information. Now , if this data was exposed via a Data Service, the payload would contain the Lat/Long/Published fields as part of the entry:content element and wouldn’t have any special meaning. The author element should be the Author field of the atom:entry , and the Published field to be the atom:published. the Lat & Long fields should be a georss element that shows the location at which the Blog Post was made. In short , it should look like this :
<entry> <id>http://localhost/AstoriaBoard/Services/BlogSvc.svc/Posts(1)</id> <title type="text">Entities, How many ways do I count thee ?</title> <summary type="html"> <img class='imgClass' width='150px' height='150px' src='/AStoriaBoard/mug.jpg'/><br/>Its a common ask that we introduce aggregatin </summary> <published>2009-03-18T14:29:43-07:00</published> <updated>2009-03-18T21:29:43Z</updated> <author> <name>Phani Raj</name> </author> <link rel="edit" title="BlogPost" href="Posts(1)" /> <category term="Blogs.BlogPost" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <content type="application/xml"> <m:properties> <d:BlogPostID m:type="Edm.Int32">1</d:BlogPostID> <d:Body>Its a common ask that we introduce aggregating mechanisms in Data services so that one can do a Count of the number of entities present in an EntitySet easily. In this blog post , I will outline one method of implementing a “Count” method that works for you. The interface to the count method will be</d:Body> <d:Author>Phani Raj</d:Author> <d:PostURI m:null="true" /> </m:properties> </content> <geo xmlns="http://www.georss.org/georss"> <long>-80.244445</long> <lat>25.730752</lat> </geo> </entry>
Now that we got this markup , I feel like we should do something with it . How about showing this information on a MAP ? I know !! We have a mapping solution , Virtual Earth , lets try and see if we can feed this feed to Virtual Earth and make it see our GeoRss markup. Recently , ( November 2008 ), the Live team released the Map control as an asp.net control . Download it here :http://dev.live.com/tools/
Add this control to an aspx page in the same website as the Data Service .
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <style> .imgClass{ border: solid 2px #99ccff;} </style> </head> <body> <form id="form1" runat="server"> <script language="javascript"> function pageLoad() { HookUpWorkAround(); } </script> <div id="mapContainer"> <ve:Map ID="geoRssMap" runat="server" Height="600px" Width="75%" ZoomLevel="4" /> </div> <asp:ScriptManager ID="scrpManager" runat="server"> <Scripts> <asp:ScriptReference Path="~/Scripts/VEWorkAround.js" /> </Scripts> </asp:ScriptManager> </form> </body> </html>
In the code-behind file ,
using System; using Microsoft.Live.ServerControls.VE; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //Clear out any mapped locations geoRssMap.Clear(); //Create a new shapelayer to import ShapeLayer geoRssLayer = new ShapeLayer(); //Point the shape layer at the data source returning the mapping information ShapeSourceSpecification georssSpec = new ShapeSourceSpecification( DataType.GeoRSS, "Services/BlogSvc.svc/Posts", geoRssLayer ); //Bind the feed to the map geoRssMap.ImportShapeLayerData(georssSpec, null, false); } }
You might be wondering why we need the HookUpWorkAround() function and what it does , I’ll explain that in a later blog post . After this , set the web page as the startup page and browse to the page in FireFox , I’ll explain why Firefox in a later blog post . And voila !! This is what the page looks like :
You can download the sample project that demonstrates this feature by clicking on the link at the bottom of this post
All this demonstrates the what and not the how , we shall discuss the how in future blog posts.
In the meantime ,enjoy this sample app and try out your own mashups.