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>In v 1.5 , through Friendly Feeds , we will now be able to assign a property of the “Customers” entity type to turn up in these element locations in the atom:entry payload.
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 ?
- entry:author/email
- entry:author/name
- entry:author/uri
- entry:published
- entry:rights
- entry:summary
- entry:title
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.