220 likes | 349 Views
Pragmatic Mash-Ups. Building POC of Web 2.0 application in one day with AJAX, Virtual Earth and Linq. Andrew Filev Microsoft Certified Architect Murano Software. Idea, scope Implementation Collecting data Getting web page Getting data with regular expressions Using REST based XML pages
E N D
Pragmatic Mash-Ups Building POC of Web 2.0 application in one day with AJAX, Virtual Earth and Linq Andrew Filev Microsoft Certified Architect Murano Software
Idea, scope • Implementation • Collecting data • Getting web page • Getting data with regular expressions • Using REST based XML pages • Selecting data: Linq, DLinq, XLinq • Displaying data • Displaying Virtual Earth map • Adding pushpins • Filtering pushpins • Future directions
Idea • To help people find their house by: • Mashing-up real estate sales ads with house valuation service and displaying ones which are priced below valuation on the map
Scope • This presentation is not covering important aspects of the whole application: • Valuation might be incorrect • How to get permission for data and valuation • It is focused on technologies • It’s about POC in a a day, not about release in a …
Implementation at the high level • Take listings • Add valuation information • Provide web-site to access this information
Getting web page • WebClient client = newWebClient(); • string pageContent = client.DownloadString(url)
Getting data:HTML+Regex <a target="_new" href="http://maps.yahoo.com/maps_result?addr=[yahoo_address];csz=...&country=US"> yahoo map</a> Regular Expression yahooStreetAddressParameter.Value = yahoo_address
Getting data:REST+XML XDocumentdoc = newXDocument(); doc.Load(String.Format(“http://www.com/webservice/GetSearchResults.htm?address={0}&citystatezip={1}”, yahooStreetAddress, yahooCityStateZip)); var result = doc.Descendants(“address”) .First().Element(“street”); streetParameter.Value = (string)result;
.NET LanguageIntegrated Query • Integration into programming language and IDE • Select, from, where, into, orderby … • XML (XLinq) and SQL (DLinq) support
DLinq: Basics • New item->DLinqObjects • Drag table from Server Explorer • Write queries in C# _context = new DataContext(connString) var results = from listing in _context.Listings where listing.Longitude <=… select listing; foreach (var item in results){ …item.Latitude… }
DLinq: Attributes [System.Data.DLinq.Table(Name="Listings")] public partial class Listing : System.Data.DLinq.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged … [System.Data.DLinq.Column(Name="YahooStreetAddress",Storage="_YahooStreetAddress", DBType="varchar NOT NULL")] public virtual string YahooStreetAddress { get {return this._YahooStreetAddress;} set { if ((this._YahooStreetAddress != value)) { this.OnPropertyChanging("YahooStreetAddress"); this._YahooStreetAddress = value; this.OnPropertyChanged("YahooStreetAddress"); } } }
Tip: how to pass connection string public partial class masterDataContext : System.Data.DLinq.DataContext { public masterDataContext(string connString) : base(connString) { } }
DLinq+XLinq XDocument xmlDoc=new XDocument( new XDeclaration("1.0", "utf-8",null), new XElement("root", from listing in _context.Listings where listing.Longitude … select new XElement("item", new XAttribute("id",listing.ID), new XAttribute("lat",listing.Latitude), new XAttribute("long",listing.Longitude), new XAttribute("price",listing.Price), new XAttribute("est",listing.Zestimate), new XAttribute("details",listing.Street))));
Displaying map <script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/v3/mapcontrol.js"> </script> <script type="text/javascript"> var map=null; function DrawMap(){ map = new VEMap('myMap'); map.LoadMap(new VELatLong(34, -118.5), 10 ,'r' , false); GetPushpins(); } … </script> <body onload="DrawMap()"> <div id="myMap" style="position:absolute; width:500px; height:400px; left: 69px; top: 117px;"></div>
AJAX request var xhr = null; function CreateXHR(){ var xhr; try{xhr = new ActiveXObject("Microsoft.XMLHTTP");} catch(e){try{xhr=new ActiveXObject("Msxml2.XMLHTTP");} catch(ex){xhr = false;}} if (!xhr && typeof XMLHttpRequest != 'undefined') {xhr = new XMLHttpRequest();} return xhr; } function GetPushpins(){ map.DeleteAllPushpins(); xhr = CreateXHR(); xhr.onreadystatechange=ProcessPushpins; xhr.open("GET", "getInfo.aspx?action=getLocations"); xhr.send(); }
Tip: move pushpinswith visible area function DrawMap(){…map.AttachEvent("onchangeview", GetPushpins);} function GetPushpins(){ … mapDiv = document.getElementById('myMap'); leftTopLatLong = map.PixelToLatLong(0, 0); rightBottomLatLong = map.PixelToLatLong(mapDiv.offsetWidth, mapDiv.offsetHeight); hr.open("GET", "getInfo.aspx?action=getVisibleLocations&left=" + leftTopLatLong.Longitude + "&top=" + leftTopLatLong.Latitude + "&right=" + rightBottomLatLong.Longitude + "&bottom=" + rightBottomLatLong.Latitude); … } public string GetItems(RectangleF LatLongBounds) { … from listing in _context.Listings where listing.Longitude <= LatLongBounds.Right && LatLongBounds.Left <=listing.Longitude && listing.Latitude <= LatLongBounds.Top && listing.Latitude>= LatLongBounds.Bottom
What might be next • Atlas • RSS consumption • Intelligent data reload • Adding/changing sources of data
Useful links • http://dev.live.com/virtualearth/sdk/ • http://msdn.microsoft.com/data/ref/linq/ • http://www.muranosoft.ru • http://www.ineta.ru • http://dotsite.ru • http://www.uneta.org