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”. 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.
Introducing Web Friendly Feeds aka Friendly Feeds Parallel Index Creation performance issue Integration
IntroducingWebFriendlyFeedsakaFriendlyFeedsParallelIndexCreationperformanceissueIntegr...
Thank you for submitting this cool story - Trackback from DotNetShoutout
As I mentioned in my last blog post , here are some samples of how to map your entity properties to Atom/custom
Phani, a data services test team member, has posted two nice write ups describing the "web friendly
Phani, a member of the data services team, has continued his great series on Web Friendly Feeds with
Rowcount:- Count and InlineCount. If you want to use Paging in your application you always need to know