Monday, 20 August 2007

Silverlight map 'saga' continues

After posting about my Silverlight/Virtual Earth overlay on RaceReplay and my plans for a Silverlight VirtualEarth viewer on codeplex, I got a friendly message from Microsoft about using the Virtual Earth tile servers "outside of the terms of service".

I figured it would be 'more responsible' to ensure that the Tile Client at least supported the Virtual Earth logo & copyright details, so I spent a bit of time working on displaying the correct copyright notice in Silverlight - the goal being that the Silverlight client would be indistinguishable from the "real thing".

Turns out Greg Shechter from Microsoft has come up with a similar concept (it's pretty obvious, after all) - a Virtual Earth Viewer (but using Silverlight 1.1, not 1.0)... (screenshot below)

It's a pretty cool sample - but even he didn't bother with the copyright; and it seems like a double-standard for MS to 'ask' me about accessing the tile images directly while at the same time releasing demo/samples that do exactly the same thing! Particularly since Greg's stuff actually works whereas my posts consist of a 4-tile proof-of-concept and a pile of ideas...

Thursday, 16 August 2007

Try doing THIS with javascript-driven maps



OK, I'm still working on getting the tile-grid 'working' beyond a simple 2x2 fixed quadkey BUT that doesn't mean we can't play around with the display capabilities of a Silverlight-hosted map control.

No, there's no business application per-se for randomly animating, zooming and translating the map tiles like this, but it looks cool (view larger image)

[OT] BTW, apparently there are some element names that "just don't work", this being one of them: <Storyboard x:Name="TimelineTranslate" RepeatBehavior="1x">. Had me confused for a minute when a SILVERLIGHT ERROR "TimelineTranslate has no properties" was thrown - but a simple name change and the animation worked.

Wednesday, 15 August 2007

Virtual Earth custom tile client (in Silverlight)



While RaceReplay.net works "acceptably" overlaying Silverlight and Virtual Earth to visualize animated/map data, it would be even better (smoother, easier to synchronize) if there was a Virtual Earth client in Silverlight, rather like this Flash map client for Yahoo Maps.

So, using tips from these instructions on
rolling your own tile server here is a first attempt at a Silverlight Virtual Earth Tile Client. I could post the source code - but as with all Silverlight 1.0 stuff, it's right there on the page!

The real question is - how much work to get from here to something that actually works?

Monday, 13 August 2007

Map-a-likes: where to map your running routes

Rundown of interactive mapping sites I've come across, primarily for mapping running (or other exercise) track data using either Google Earth or Microsoft Virtual Earth/Live Maps... (no, I haven't seen one using Yahoo Maps yet). Some require you to draw/trace the route, others allow upload of GPX, KML or other GPS-format data.

MapMyFitness
Includes MapMyRun, MapMyRide and MapMyTri. Uses Google Maps to draw routes, enter training data and search for others. Imports Gpx and from gmap-pedometer. Exports to Kmz. 5 star favourite.
www.mapmyfitness.com

Gmap-Pedometer
The original (as far as I'm concerned) - if there was a site around before this one, I didn't find it.
www.gmap-pedometer.com

MotionBased
Focussed on GPS data integration using Google Earth maps - since I don't have any toys, haven't really used it. Apparently has lots of 'analysis' features for your data & fitness.
www.motionbased.com

ShareMyRoutes
Uses Microsoft Virtual Earth. Exports to Gpx and Kml.
www.sharemyroutes.com

CompareTracks
Not so much a website, but a piece of software to manage maps (see NYC below)
www.comparetracks.com

ninemsn's rip-off site
Rip-off of my favourite site (above) at mapmyfitness.ninemsn.com.au - slow maps and pretty basic functionality.

BikeMap.de
In German, but you get the idea...
www.bikemap.de

Run.com
Great URL but seems relatively new (ie. very few runs in the database)... uses Google Maps.
www.run.com

and for watching only

BBC
Tour de France map - the BBC always does great stuff on the web.

New York City Marathon
NYC marathon simlator requires Java, and provided by Sportsim (who have open-sourced their software as CompareTracks - see above).

...and "sorta" related
RunPix
RunPix doesn't have an interactive map, but does do 'race statistics visualization', including a static map of where you were on the course when the leaders finished.

Thursday, 9 August 2007

RaceReplay 'RC1' (now with Silverlight & Virtual Earth)


www.racereplay.net release 3 is now live:The Designer will be mortified that I've munged the beautiful work he did by adding those dodgy arrows, but I'm sure you'll agree it's a big improvement!

Tuesday, 7 August 2007

When non-runners strike...



This is what happens when a "non-runner" publishes a race map on the web... That's a big jump off the Cahill Expressway onto Macquarie Street, guys.

Who would do such a thing? It's ninemsn's new "mapmyfitness" site, with a blatant ripoff (even the name!) of a better established, better written US-based site http://www.mapmyfitness.com/.

Too bad the ninemsn site is slow as a wet-week - I "think"' they've missed the point about JSON being light-weight
value="[
{"__type":"Ninemsn.Simba.WebControls.VE.ShapeLayer,
Ninemsn.Simba.WebControls, Version=1.0.2708.32310, Culture=neutral,
PublicKeyToken=null","Title":"Edit
Layer","Description":"","Shapes":
[{"__type":"Ninemsn.Simba.WebControls.VE.Shape,
Ninemsn.Simba.WebControls, Version=1.0.2708.32310, Culture=neutral,
PublicKeyToken=null","_id":null,"ShapeType":1,
"Title":null,"Description":null,"CustomIcon":null,
"CustomType":"Line","PhotoUrl":null,
"Points":[{"__type":"Ninemsn.Simba.WebControls.VE.LatLong,
Ninemsn.Simba.WebControls, Version=1.0.2708.32310, Culture=neutral,
PublicKeyToken=null","Latitude"
:-33.8479105875013,"Longitude":151.211593151093},
{"__type":"Ninemsn.Simba.WebControls.VE.LatLong,
Ninemsn.Simba.WebControls, Version=1.0.2708.32310, Culture=neutral,
PublicKeyToken=null","Latitude":
-33.8460304508373,"Longitude":151.211292743683},
or, if you preferred:
value="[
{"Title":"Edit Layer"
,"Points":[
{"Latitude":-33.8479105875013,"Longitude":151.211593151093}
,{"Latitude":-33.8460304508373,"Longitude":151.211292743683}
,{"Latitude":-33.8450770007942,"Longitude":151.211131811142}
Okay okay, I'm being harsh - maybe it's generated output from astoria - but the maps are slow to navigate. I wonder how the sponsor "Kellogg's Special K" feels about it - maybe they should go back to ninemsn to get it sped up (and maybe the map resized?)

Road view - big jump!Satellite view - big jump!

It's certainly no "RaceReplay" :)

Wednesday, 1 August 2007

Silverlight 1.0 RC - bug fixed!

Yes, RC1 of Silverlight 1.0 has been released (in case you missed the announcements).

Thankfully the breaking changes haven't really affected the stuff I've been playing with - it's been a fairly painless change to swap in the updated Silverlight.js file and tweak the createSilverlight() function (Sys.* has been removed - shouldn't clash with ASP.NET AJAX now):
Silverlight.createObjectEx({
source: 'Scene.xaml',
parentElement: document.getElementById("SilverlightControlHost"),
id:'SilverlightControl',
properties:{
width:'100%',
height:'100%',
framerate:'24',
enableFramerateCounter:false,
version:'1.0'},
events:{
onError:null, onLoad:null, onResize:null
},
context:null
});
What's even better is that it fixes the bug on this 400-element animation. The beta used to just 'freeze' about two-thirds of the way through the animation: all the dots stopped moving until the timeline 'finished', then they'd all disappear (jump straight to end). Now it works seemlessly - time to try it with more animated objects!

Monday, 23 July 2007

What is Astoria?

While I wait for amazon to deliver RESTful Web Services, there's plenty to read on the web...

Jon Udell posts an interesting example of a RESTing transaction... seems to me there are very few 'example interactions' around to help people understand how REST is 'different', so it makes an interesting read.

If you prefer an explanation rather than a lot of reading, watch Pablo Castro introduce Astoria Data Services (pre-MIX) and at MIX "Accessing Data Services in the Cloud" (then subscribe to his blog about Astoria and Entity Framework stuff).

SOT: If, like me (after doing a bit of reading about REST and then JSON), you started to wonder if JSON isn't superior to Xml in many respects, you'll want to download JSON Viewer as you start to build applications with it.

P.S. How do you get a job like Pablo's?

Monday, 16 July 2007

Microsoft admits: "Xml isn't everything"

With Xml, Serialization and Web Services baked into the first .NET Framework at a time that the Java world only had fairly rudimentary optional add-ons, it seemed like Microsoft was 'finally embracing an open standard' ahead of the curve... Xml has continued to become a cornerstone of .NET and Office (and BizTalk, and SharePoint, and...) ever since.

The "problem" with Xml is the growing 'weight' of Xml implementing even a basic solution "properly" - namespaces, XSD, WSDL, SOAP, WS-* standards, etc. It's no longer just a simple case of throwing a few tags together to get something done.

While Microsoft continued down the Xml-and-WS-in-.NET road, others (the Ruby community, for a start) popularised Representational State Transfer (REST Web Services).

It's light-weight and much easier to use with AJAX and other RIAs, in part because it's not Xml-centric but open to simpler 'data syntax' such as JSON. JSON slots seemlessly into browser script interpreters without pesky translations or reliability on XmlHttp implementations, so the cross-browser/standards crowd cottoned on quickly. Even 3rd party Microsoft solutions like Ajax.NET Pro used JSON.

Which brings us back to Microsoft, who appear to have 'got the message'.

MSDN recently featured an Introduction to JavaScript Object Notation (JSON) in JavaScript and .NET, comparing JSON to XML, and then subsequently released Astoria at Mix07 (an announcement likely overshadowed by the release of Silverlight).

Astoria enable(s) applications to expose data as a data service that can be consumed by web clients within corporate networks and across the internet. The data service is reachable over regular HTTP requests, and standard HTTP verbs such as GET, POST, PUT and DELETE are used to perform operations against the service.
The payload format for the service is controllable by the application, but all options are simple, open formats such as plan XML and JSON.
The use of web-friendly technologies make it ideal as a data back-end for AJAX-style applications, Rich Interactive Applications and other applications that need to operate against data that is across the web.

Compare the request format
http://astoria.sandbox.live.com/encarta/encarta.rse/Articles[Title%20eq%20'Aerobics']?$expand=RelatedArticles to a comparable SOAP-formatted request... and if it wasn't disabled by default, you'd get JSON back instead with http://astoria.sandbox.live.com/encarta/encarta.rse/Articles[Title%20eq%20'Aerobics']?$expand=RelatedArticles&$format=json

For now Astoria is an alpha/beta to help us become familiar with the concepts behind it. It is (apparently) based on Windows Communication Foundation (.NET 3.0), so it may not end-up being as 'light' as you think.

Would/could/should you base your SOA on REST/JSON, or stick with XML/SOAP? The answer may be in O'Reilly's RESTful Web Services, but then there's no substitute for trying it out yourself... your application's authorization, authentication, topology, scalability, complexity, distribution, platform, usergroup/s can only begin to guide you towards the right decision.

UPDATE: Came across these links after posting:
Will Web 2.0 displace the WS-* protocols?
The Merging of SOA and Web 2.0

Tuesday, 10 July 2007

Synchronized dragging: Silverlight and Live Maps/Virtual Earth

Further to this post on Synchronizing Live Maps & Silverlight canvas, you can now pan by dragging rather than just using the rather clumsy up/down/left/right links: both the Silverlight Canvas containing the animation AND the underlying Microsoft Live Maps can be dragged (together)!

You can try out the demo of a Silverlight & Live Maps overlay with synchronized dragging to pan (it's not yet integrated into RaceReplay.net).

It was a relatively simple implementation of the sample code provided by then Silverlight Mouse Support documentation on MSDN. As with most Silverlight stuff, you can just View Source to see how it works...

Look out MapCruncher (joking!)

UPDATE: zooming now works too. When 'implementing' the Mouse Support example, I blindly copied
    canvasT.X = canvasPixel.x;
canvasT.Y = canvasPixel.y;
into onMouseUp(), forgetting that I was also updating
        sender["Canvas.Left"] += currX - beginX;
sender["Canvas.Top"] += currY - beginY;
in onMouseMove(). Oops. Better to update that same property and avoid applying the 'transformation' twice...
    sender["Canvas.Left"] = canvasPixel.x;
sender["Canvas.Top"] = canvasPixel.y;
Also added a new cursor to indicate the map is 'draggable' - unfortunately Silverlight has a limited set of cursors to choose from, so the hand-pointing is used rather than open-hand.

Wednesday, 4 July 2007

Thinq Linq

If your initial impressions of Linq are that it's mainly for data-access (because of the syntax similarities to SQL, and the availability of Linq to SQL), thinq again!

The Linq Cookbook (although in Visual Basic) demonstrates the sorts of problems you can now solve in a couple of lines of code:
  • Change the font for all labels on a windows form

  • Find all capitalized words in a phrase and sort by length (then alphabetically)

  • Find all complex types in a given assembly

  • Find all the prime numbers in a given range

  • Concatenating the selected strings from a CheckedListBox

If you do want to read more about Linq and SQL/data access, Explore LINQ, SQLMetal and SqlTac courtesy of Red-Gate.

Wednesday, 27 June 2007

"Corporate"Book?

Interesting article about Facebook for the Enterprise.
"Today, I see a combination of Twitter and Facebook as having the potential to replace 90% of the email I receive while improving my personal productivity."

Many companies still don't see IM as anything other than a nuisance to be blocked, so it's sorta interesting to think about whether spending time on Facebook can be 'productive'.

Quote from Facebook generations
"...my 14-year-old daughter is appalled that I am a member of Facebook, and refuses to let me friend her, lest her other friends find out via News Feed."
raises an issue with I suspect would extend into "Corporate"Book - do you really want everyone knowing everything about you... at work?

[sot] Apparently Australia is the 5th biggest Facebook community, after USA, Canada, UK & Norway!

UPDATE: Looking for Facebook applications or ideas? - someone's already started a 'portal' for Facebook apps and news. Helps find neat new stuff, like the Facebook ToolBar for Firefox - because you don't spend enough time checking Facebook already...

Saturday, 23 June 2007

Synchronise Live Maps & Silverlight canvas


If you overlay a location-specific Silverlight canvas on a Live Map (or is it Virtual Earth?, you'll probably want to 'synchronise' the canvas with the underlying map as it is panned/zoomed.

Although it might seem a tough task, with the help of the Virtual Earth 5 SDK it's relatively easy.

Firstly, check out the end result - a Silverlight canvas/animation that zooms and pans with the Live Map underneath it.

To accomplish the effect, I needed to:

0. Load the map and Silverlight controls
map = new VEMap('myMap');
map.LoadMap(
new VELatLong(-33.865052673579655, 151.22375965118408),
16, VEMapStyle.Hybrid);
//...
Sys.Silverlight.createObject( "xaml/Domain.Xaml", ...
Remembering to set isWindowless:'true' and the position of the elements so they float together.

1. Add Scale and Translate Transforms to the canvas
lt;Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"
x:Name="canvasScale" />
<TranslateTransform X="0" Y="0"
x:Name="canvasTranslate" Name="canvasTranslate" />
</TransformGroup>
</Canvas.RenderTransform>
(this was the only change required to the Xaml). You will use the x:Names later to make it easy to transform the canvas.

2. Determine the lat-long of the canvas

So that you can always position it accurately, regardless of how the map has been panned or zoomed. In this case, the top-left of the canvas should be is at 33.858210507117995, 151.2127733230591, and the map center when loaded is -33.865052673579655, 151.22375965118408.

3. Support panning
Simply shift the map and canvas by the same pixel delta, eg. simply call the Pan function on the map object, and modify the named TranslateTransform on the canvas.
function MoveNorth()
{
map.Pan(0, -100);
var sl8 = document.getElementById("WpfeControlHost_1");
var canvasT = sl8.content.findName("canvasTranslate");
//canvasT.X = canvasT.X - 100;
canvasT.Y = canvasT.Y + 100;
}

4. Support zooming
Other than a little bit of hardcoding, the zoom javascript is pretty simple
function ZoomIn()
{
map.ZoomIn();
var zoom = map.GetZoomLevel();
media_scale(zoom);
return false;
}
function media_scale(zoomLevel)
{
var sl8 = document.getElementById("WpfeControlHost_1");
var canvasT = sl8.content.findName("canvasTranslate");
var canvasS = sl8.content.findName("canvasScale");

var canvasLatLong = new VELatLong(-33.858210507117995, 151.2127733230591);
var canvasPixel = map.LatLongToPixel(canvasLatLong);

canvasT.X = canvasPixel.x;
canvasT.Y = canvasPixel.y;

if (zoomLevel == 17)
{
canvasS.ScaleX = 2;
canvasS.ScaleY = 2;
}
else if (zoomLevel == 16)
{
canvasS.ScaleX = 1;
canvasS.ScaleY = 1;
}
else if (zoomLevel == 15)
{
canvasS.ScaleX = 0.5;
canvasS.ScaleY = 0.5;
}
else if (zoomLevel == 14)
{
canvasS.ScaleX = 0.25;
canvasS.ScaleY = 0.25;
}
else if (zoomLevel == 13)
{
canvasS.ScaleX = 0.125;
canvasS.ScaleY = 0.125;
}
else if (zoomLevel == 12)
{
canvasS.ScaleX = 0.0625;
canvasS.ScaleY = 0.0625;
}
// haven't supported tinier zoom levels - might need to just hide content?
}

As long as your canvas and map loaded 'in sync', the panning should work without trouble, and if the top-left lat-long of your canvasis set, zooming should work too. Note that the scale-factors will depend on what 'resolution' your original Xaml was drawn in - I was tracing a map at zoom level 16 (as you can see).

There's a lot more you could add to this - including animating the zoom and supporting 'drag' for the canvas and map...


Thursday, 21 June 2007

Silverlight/Live Maps overlay

sydney landmarks is based on
Using Opacity with a Silverlight / Virtual Earth Mashup (Remix) - in addition to changing the locations it's also using v5 of the map sdk (rather than v4).

The idea is to eventually get RaceReplay.net working with 'live' maps rather than using embedded images.

No source is "posted" - it's all right there in the browser for the View Source Reflector tool for Silverlight to see.

Monday, 18 June 2007

New code online...

New code uploaded on

RaceReplay.net - more courses, satellite imagery

RecipeNow.net - new look, SEO friendly pagenames (Silverlight 'recipe book' "coming soon")

Nothing new on Searcharoo.net but came across some more 'users': Ultimate Safari, Health service. Kinda funny seeing it in the wild.

Saturday, 16 June 2007

Silverlight z-order, html layering, etc

Took longer that it should to figure this one out: the Silverlight control on RaceReplay.net was obscuring the CssControlAdaptor menus.

Anyway, short story is that the solution is simple - WindowlessMode - and is introduced in this post on Using Opacity with a ... Mashup.

However, it shows javascript new agHost for "WPF/E", which looks slightly different now we have "Silverlight", so find your createSilverlight() function and add the bolded line (don't forget the comma):
function createSilverlight()
{
var scene = new Blend1.Scene();
Sys.Silverlight.createObjectEx({
source: "Scene.xaml",
parentElement: document.getElementById("SilverlightControlHost"),
id: "SilverlightControl",
properties: {
width: "100%",
height: "100%",
version: "0.9",
isWindowless: "true"
},
events: {
onLoad: Sys.Silverlight.createDelegate(scene, scene.handleLoad)
}
});
}
[UPDATE] isWindowless works just fine on:

  • Windows/IE

  • Windows/Firefox

  • MacOS/Firefox - Css menus look/work great versus the standard ASP.NET control

... but there seems to be a little problem with MacOS/Safari -- the menus pop-down behind the Silverlight control (making them slightly useless) BUT if you know their content, the mouseclick actually seems to go through the Silverlight control and trigger the relevant menuitem/link! Weird.
BTW, Silverlight doesn't even install on Safari 3.0 for Windows (yet)

Friday, 15 June 2007

HtmlAgilityPack rocks (again)

I've said it before, but have to say it again... the HtmlAgilityPack is awesome.

If you are doing any sort of scraping or other Html processing and aren't using it, you're writing too much code!

Today's task was parsing 38 html pages of html-tabular data into SQL INSERT statements (37,919 statements in the end). Create a ConsoleApplication, using System.IO and HtmlAgilityPack, and use this Main (redirecting the output to a textfile program.exe > inserts.sql)

string[] filenames = Directory.GetFiles(@"C:\Temp\", "*.htm", SearchOption.TopDirectoryOnly);
foreach(string filename in filenames)
{
string file = File.OpenText(filename).ReadToEnd(); // parsing out the <table> i want here
int tableStart = file.IndexOf("<table"); tableStart = file.IndexOf("<table", tableStart + 1);
int tableEnd = file.IndexOf("</table>") + "</table>".Length;

string table = file.Substring(tableStart, tableEnd - tableStart) + Environment.NewLine;
HtmlAgilityPack.HtmlDocument hd = new HtmlDocument();
hd.LoadHtml(table); // you can load a fragment, in this case just a <table></table>

HtmlNode tableNode = hd.DocumentNode.ChildNodes[0];
foreach (HtmlNode rowOrText in tableNode.ChildNodes)
{
if (rowOrText.NodeType == HtmlNodeType.Element)
{
if (rowOrText.Name == "tr")
{
if (rowOrText.Attributes["class"] == null) // only 'header' rows have a class in my example
{
String Place = rowOrText.ChildNodes[0].InnerText.Trim();
String Name = rowOrText.ChildNodes[3].InnerText.Trim();
String Time = rowOrText.ChildNodes[4].InnerText.Trim();

Console.WriteLine("INSERT INTO RaceRunner ([Name], [Time]) VALUES ('{1}', '{2}')", Name, Time);
}
}
}
}
}

p.s. in case you were wondering, the source Html was NOT valid Xml that could be loaded into XmlDocument or other built-in .NET class
p.p.s. I really must find a reliable code prettifier...

Thursday, 14 June 2007

Facebook takes off...

The 3 week old 'Facebook Platform' is getting some interesting write-ups, not only that but they've partnered with Microsoft (/Popfly) to give Yahoo Pipes a run for it's money.

Furthermore, all of a sudden everyone I know is on Facebook.com, so I'm uploading photos of
Cuba and Mexico there as well as on Flickr (maybe there's a mashup to 'share' them, but couldn't be bothered with that for now).

Where will social networking go now?

EDIT: As if in answer, SMH published OMG, mum's joined Facebook! today...

EDIT2: (the other?) Paul Allen makes a big call: Prediction: Facebook will be the largest social network in the world. There's additional coverage in SMH 19-Jul-07, but the article isn't online...

Friday, 8 June 2007

ASP.NET Ajax vs Silverlight

Not quite 'Alien vs Predator', but an interesting experiment nevertheless.

I stumbled across this post using the ASP.NET Ajax AnimationExtender to move points around and immediately recognised the similarities to the Silverlight 'race simulator' demos I've been playing with.

It seemed a natural progression to try animating same North Head (Sydney) race runner data using ASP.NET AJAX to animate the runner markers. A quick massage of the Silverlight XAML (using Excel!) and I had a couple of JSON arrays ready to go.

The result, as you can see, is not quite as smooth as Silverlight - and I suspect that Ajax would have even more trouble than Silverlight with 400 elements to animate!

You can View Source of the AJAX page - it's all there.

Saturday, 2 June 2007

Silverlight docs (link drop)

Silverlight Learning Guide is a very complete list of links about Silverlight (1.0 and 1.1), including this one which helps explain the connection between Ruby/Python and C#/VB.NET (dynamic vs 'managed'?) langauges : Clearing the air about Silverlight and the DLR.

OT1: Awesome video explaining Seadragon and Photosynth technologies from MS research. Seadragon seems like a natural progression from a viewer like Flickrleech.
Ultimately the 'player' for both should/would be Silverlight (you'd think...) The Photosynth 'Notre Dame' poster example is cool (WOT: parts of the Photosynth site are Flash9 :)

OT2: Apple will want to release a non-iPhone multitouch iPod before Microsoft launches a milan/surface based Zune

Tuesday, 29 May 2007

RaceReplay.net released

RaceReplay.net is 'live'... well, in beta form anyway.

Turns out Silverlight is a great medium for .NET developers to get on the RIA bandwagon. Flash always had a big learning curve - probably due to it's "designer-focused" background - but Silverlight and Xaml just seems to 'make sense' (to me, at least).

OT: Russ just pointed me to Flickrleech - waaay cool viewer for flickr photos.

EDIT: Silverlight vs. Flash: The Developer Story is an interesting point-of-view... although it was a loong time ago that I last developed anything in Flash, certainly they Silverlight platform makes a lot more "sense" to me.

Thursday, 10 May 2007

More Silverlight

First, thought this platform comparison (Silverlight v Flash) was interesting - not sure how complete it is thought (and it's a bit early to claim Silverlight has a "Robust video publishing tools and third-party ecosystem" but Flash does not. Thought the SEO angle was interesting (wonder how many engines do follow links to "Xaml-behind", and not sure 'DRM' is a feature everyone likes.

Anyway, the saga of RaceReplay continues... after getting race splits (mostly) working I decided to give Silverlight a 'stress test' by loading all 400 competitors into the simulation (warning: the Xaml-behind is 7Mb, so loading may take a while).

The first thing that came to mind was "that Xaml is too big!". One way to solve this will be to send the animation data via JSON and pump Xaml from Javascript into Silverlight - pretty sure that will be a lot less verbose than repeated

While googling for other options, it turns out Silverlight also supports the ZIP format. The post suggests using it to package images, but ZIPping up Xaml (text/xml) would surely show much better compression gains - my 7Mb animation canvas compresses to 576kb, so now all I need to do is figure out if it's possible to extract and inject it into the Xaml DOM. Will see how that goes - the City2Surf has 60,000 runners (wonder how close Silverlight will get to animating those...)

Sunday, 6 May 2007

Playing with Silverlight...

After mapping race courses, the next logical step seemed to be visualizing the races themselves, similar to BBC Tour coverage (link thanks to Russ) and at least one overseas marathon I've seen online (but can't remember which).

This 10k race demo shows how it could work, using Microsoft Silverlight beta 1.0 and Microsoft Expression Blend.

Got some other Silverlight ideas... stay tuned.

EDIT: Now calculates km markers automatically, and shows altitude as well. Now it really needs to support split times rather than race-average (so the 'runners' slow down on the hills!)

EDIT2: Although some 'matrix glitches' are present, km splits are now supported. Watch red catch green in the 2nd lap! The 'jumping' is due to a bug when a line segment is "split" to accomodate an intra-segement marker... kinda know where it is but too late (at night) to fix it now...

Sunday, 29 April 2007

Linqaroo I

Playing with 101 LINQ samples and Searcharoo...

The simplest query (say, for the word "recent") over the existing 'index' looks like this
var x = from wf in catalog.WordFiles
where wf.Text == "recent"
select wf;
Digging deeper into the HashSet introduced in .NET 3.5, boolean search queries (which took ages to discuss & code in Searcharoo 2) can be easily described in Linq


so that a simple method call


will produce the these results (Console Apps - the easiest way to play with any new tech :)


Of course there's little indication of well it performs, or how it will work in the code itself (no query tree parser yet, so some work still to do)... maybe i4o - Indexed LINQ will come in handy, or at least provide some ideas for proper Searcharoo-backed Linq classes.

EDIT 30-Apr: It seems possible to play with the underlying structure of LINQ in .NET 2.0, although there's a bit more work to do exploring how robust the implementation is and how good the 3rd party (Hash)Set class is.

Monday, 2 April 2007

Searcharoo.net gets a facelift...

The Searcharoo.net website has a new skin... much less 'fluro' than the old one (below :)



and a new, improved RecipeNow.net is coming soon...

Wednesday, 28 March 2007

Compact Framework... link drop

It's been a while since I've worked on CE/mobile, but getting back into it. All the stuff that's new/changed since my last 'real' mobile app makes for interesting reading...

What's New for Developers in Windows Mobile 6

Windows Communication Foundation (Compact Edition) is a great read.

OpenNETCF was an essential reference last time I checked...

Synchronization Strategies: email?!

SQL Server CE - latest name for SQL Everywhere; no it doesn't just run on Windows CE...

Thursday, 22 March 2007

'Declarative' Google Maps - store locator sample

Just added another 'sample' app:
Store Locator: Help customers find you with Google Maps to CodeProject.

I started playing with GMapEZ declarative Google Maps API in Feb, originally just for mapping 'race' courses in Sydney for my running club. Later adapted it for a couple of 'proof of concept' samples related to mapping customer data and delivery truck routes (using Google's driving directions feature).

As well as the article, you can play with the NeedCoffeeNow sample online.

Monday, 19 March 2007

Open DOCX using C# to extract text for search engine

Parsing text-content out of different file formats for Searcharoo (or other search engines) can be accomplished a number of ways, including writing your own parser (eg. not too difficult for Html) or using an IFilter loader.

However there's always going to be new document types or formats where you want to build a custom parser... and today the new Word 2007 DOCX format is an example: I don't have Word 2007 installed on my PC so I doubt there's any IFilter implementations for it lying around here either.

A bit of background: the DOCX format is basically a ZIP file containing a directory-tree of Xml files, and from what I can gather the main body of a (Word 2007) DOCX file is located in word/document.xml within the main ZIP archive.

Using a .NET ZIP library based on System.IO.Compression it's relatively simple to open a DOCX file, extract the document.xml and read the InnerText, like this:
using System;
using System.IO;
using System.Xml;
using ionic.utils.zip;
... your code to populate the DOCX filename here ...
using (ZipFile zip = ZipFile.Read(filename))
{
MemoryStream stream = new MemoryStream();
zip.Extract(@"word/document.xml", stream);
stream.Seek(0, SeekOrigin.Begin); // don't forget
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(stream);
string PlainTextContent = xmldoc.DocumentElement.InnerText;
}
If you're using NET 3.0, the System.IO.Packaging.ZipPackage class is probably a better bet than the open source ZIP library for 2.0.

Now to do some reading on XLSX and PPTX formats...

Sunday, 18 March 2007

Don't forget SQL Server 2005 'Compatibility Level' (ARITHABORT error on Xml query)

Working on a database recently that has been 'upgraded' from SQL Server 2000 to 2005. As part of the process, I added some 'Tools' stored procedures I commonly use (eg. ScriptDiagram).

For "some reason" that wasn't immediately obvious to me, I could execute these procs without trouble in SQL Server Management Studio BUT when I added some C# code that referenced a '2005-feature' stored procedure (such as using the new xml column.query syntax)...

SELECT failed because the following SET options have incorrect settings: 'ARITHABORT'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or query notifications and/or xml data type methods.

I started off trying to debug the C# code, thinking I'd done something wrong there... but then realised the Database Properties - Options - Compatibility Level must still be set to SQL Server 2000 (80). Changing that to SQL Server 2005 (90) got rid of the SELECT failed error... because I hadn't really 'upgraded' the database at all, just restored a 2000 backup into 2005.

Why the queries work in Studio still confuses me a little bit... but I'll worry about that some other time. Hope that helps someone - I didn't find anything useful on my first google for the error message.

Saturday, 17 March 2007

Searcharoo C# search engine indexes Word, PDF and more...

The latest version of Searcharoo (4) is now available for download (and read about, of course) --
C# search engine: refactored to search Word, PDF and more.

The coolest feature - searching Microsoft Office docs (Word, Excel, PowerPoint) and Acrobat/PDF files - is based on someone else's article Using IFilter in C#.

Also put a bit of work into refactoring the code structure, layout, naming, etc. At least now it might pass a "code review" (if anyone cared to conduct one:)

The project now also has it's own website www.searcharoo.net - the latest article isn't quite there yet (requires some formatting) but over time I'll post more frequently to that site; it takes forever to write, format and upload decent, CodeProject-quality work...

Thursday, 22 February 2007

Parsing DBP (Visual Studio Database Project) files

I was surprised how few people appeared to be trying to 'parse' Visual Studio Database Projects (*.dbp files). Why is it useful? If you want to construct a database from scripts in a project, you want to get exactly those scripts run - not any others that might be lying around the filesystem because Studio was too lazy to 'delete' them when they were removed from the Project (or perhaps they were retrieved from VSS).

Captain LoadTest had the same issue in 2005, and developed a
NAnt script to parse VS.Net database project files, which is a nice idea - but I really wanted to access the 'tree' of scripts from C#.

Thankfully, the open-source project AnkhSVN (which integrates the Subversion source control tool into Visual Studio) has exactly the code needed: ParsedSolution.cs and ParsedSolutionItem.cs.

I commented out some code ('context') and added this method, and that pretty much worked. Make sure you check the licence before using...
/// <summary>
/// Borrows code from the solution parser to JUST parse Database Project Files
/// </summary>
/// <param name="projectFileName">The full path to a *.DBP file</param>
public static ParsedSolutionItem OpenDatabaseProject(string projectFileName)
{
string projectFile = projectFileName; //GetProjectFile(projectFileName);

ParsedSolutionItem project = new ParsedSolutionItem();
project.Name = "Database"; //projectName;
project.FileName = projectFile;

if (System.IO.File.Exists(projectFile))
{
using (StreamReader reader = new StreamReader(projectFile))
{
string extension = Path.GetExtension(projectFile);
switch (extension)
{
case ".dbp":
ParseDatabaseProject(project, reader);
break;

default:
throw new ApplicationException("Trying to parse unknown project of type " + extension);
}
}
return project;
}
else
{
return null;
}
}

Tuesday, 17 October 2006

How to program it...

This brief 'essay' on developing a functional algorithm How to program it... is based on a 1945 book describing methods of problem solving.

The four basic steps are:
  1. First, you have to understand the problem.

  2. After understanding, then make a plan.

  3. Carry out the plan.

  4. Look back on your work. How could it be better?


I think it should be required reading for all developers - even pasted on your cubical wall!

Particularly when hiring, one of the "metrics" I try to measure in candidates is their sense of 'logic'. This is easier said than done, however; and actually what I am really interested in their natural ability or inclination to follow such a process.

It's easy to spot less 'logical' developers. They start at (and sometimes only ever do) Step #3! Sometimes, in the process of thrashing about in Step #3 they may accomplish some of Step #1. While fixing the inevitable bugs, they may also accidentally get some Step #4. But it's not an efficient process...

Sunday, 3 September 2006

The best developers are built not bought

The best developers are built not bought

At the very bottom of Bloom's taxonomy of educational objectives for cognitive skills is knowledge. That is recall (or recognition) of data or information. Applied to development terms this means recognizing the C# syntax or recalling the correct syntax to execute a loop.

At the top of the cognitive taxonomy is synthesis and evaluation. Synthesis is to be able to bring together diverse elements to form a new whole solution. Evaluation is the ability to make judgments about the value of ideas, approaches, or materials. Developers need to consistently apply these higher levels of cognitive ability to effectively perform their work.

Most people find the idea expressed as thinking more natural than describing the difference as cognitive process. In general, the more thinking that is being done about higher level ideas, such as how to integrate pieces to form a solution, the better the developer.

Sunday, 20 August 2006

Visual Studio 2005 Snippets - literal dollar sign $$$

Been using Visual Studio 2005 snippets since I installed it... double-[tab] is a common keystroke now. Of course, my first attempt to create a Snippet wasn't as simple as it should be thanks to the dollar sign escaping of variables. I wanted a 'standard' VSS region-wrapper as a snippet (yes, I realise I can also add it to our class file template).
#region Page History
/*
* $History: $
*/
#endregion
but the editor interprets $History: $ as a variable and doesn't display it. Tried Google, but not easy to search for '$' and get useful results... after a few false starts trying to Xml entity encode it (ie. &#62;) which also didn't work, I tried the double-dollar-sign $$ at random - and it worked!

Got Snippets is a great place to start when looking for useful snippets (or ideas/samples to build your own). Some of them are pretty complex.

Some other useful snippet links:

Monday, 10 July 2006

Generics, Serialization and NUnit

Latest article Generics, Serialization and NUnit posted on CodeProject.com. The googling I've done so far hasn't turned up much info on Unit Testing and Generics... seems to me that any time you write a class, you want to be able to test it, and Generic classes should be no exception; but there's not much support in NUnit for it at the moment...

Monday, 3 July 2006

NCover 'connection not established' error

I recently tried to set-up NCover 1.5 with a .NET 2.0 project on a new PC, but could not get past the error message Profiled process terminated. Profiler connection not established... the BAT file I was using looked like this (and was working fine on the build server)
@echo off
C:\DevTools2\NCover-1.5\NCover.Console.exe "C:\DevTools2\nunit-2.4.b1\bin\nunit-console.exe" "C:\Projects2\APPNAME\UnitTests\APPNAMEUnitTests.nunit" //a "Common.APPNAME.DataAccess;Common.APPNAME.Common; Common.APPNAME.RulesEngine;Common.APPNAME.Client" //ea "Common.CodeCoverageExcludedAttribute" //w "C:\DevTools2\nunit-2.4.b1\bin" //l "C:\Projects2\APPNAME\Build\NCover\NCover.log.txt" //x "C:\Projects2\APPNAME\Build\NCover\NCover.xml"


Of course, because NCover was working OK on other .NET 1.1 projects, I immediately assumed it was a 'framework' issue and spent fruitless time trying to 'figure out' why NCover couldn't "connect" to my application.

I gave up, only to be embarrassed a day or two later when this
NCover Error Message thread: Profiled process terminated. Profiler connection not established gave me the simple solution: I needed to register one of the NCover components (presumably so it can hook in to the CLR instrumentation or whatever)
regsvr32 CoverLib.dll

Doing an install of NCover from the .MSI would also have worked, but I've gotten so used to .NET applications being able to be 'xcopied' that I had just moved the NCover files from one PC to another and expected them to work.

Thursday, 22 June 2006

atlas:UpdatePanel Cancel/Abort UpdateProgress

Thanks to this blog Trabalhando com o ASP.NET Atlas Framework - Parte III for finally giving me the hint on how to add a Cancel/Abort option to the atlas:UpdatePanel UpdateProgress template.

Just add an <input runat="server" type="button"> <asp:LinkButton id="abortButton" runat="server">

The trick is id=abortButton! You don't need to add any further client or server code/jscript/whatever. The presence of that control id is enough. When the UpdateProgress is displayed, you can click to cancel the Ajax XmlHttpRequest.

Why was this so difficult to figure out? I guess because if you use the Designer to create the ProgressTemplate it adds the button for you... but i was creating the controls in Source view, and it was NOT immediately obvious how the Abort/Cancel should be implemented.

EDIT 22-Feb-07 This post is out-of-date; the released version of ASP.NET AJAX doesn't work this way... just one of the breaking changes - check the Migration Guide: Converting Applications from “Atlas” CTP to ASP.NET AJAX RTM

Sunday, 18 June 2006

,NET 3.0!

How did I not already know this... .NET Framework 3.0 will be released with Vista, and available for Windows XP and Windows Server 2003.

Interestingly (I think) it will just compile with the existing FX2.0 CLR, so I guess WinFX is just a mass of managed code? Still doesn't include LINQ or ObjectSpaces, so for database-focussed (ie. business) applications, what benefit does the renamed WinFX provide?

OT: great discussion-starter on Who needs value types anyway?, and this on .NET Framework 3.0 Naming...

Monday, 12 June 2006

RefreshPanel: precursor to Atlas

The Atlas UpdatePanel control seems to have it's genesis in the April 2005 RefreshPanel on gotdotnet.

The UpdatePanel has it's own 'book lite' on OReilly.com - USD9.99 doesn't seem to bad, although the fact they want to charge 'delivery' for overseas customers is very frustrating! The PDF itself is like an extended CodeProject article...

Sunday, 4 June 2006

Migrating to *ASP*.NET 2.0... from a Class Library project

In ASP.NET 1.1, Web Projects and the way they bind to Visual SourceSafe and a specific website make it *very* difficult to manage. I have always followed this advice to use
ASP.NET without web projects: the Project becomes a class library, and with a few minor VisualStudio configuration changes the source-control integration becomes a LOT easier.

But what happens when you want to migrate to ASP.NET 2.0? Do you:

  1. keep using the 'class library hack', but maybe forgo VisualStudio 2005's cool new features for ASP.NET Designer Support

  2. convert back to a Web Project in 1.1 then migrate to 2.0 (ie undo/reverse these instructions)

  3. migrate the 'class library' project to 2.0 first, then convert it to the new (ie post Visual Studio 2005 released add-in) Web Application Project/li>
  4. create a Web Site Project and copy all the existing pages into it

  5. or something else...



If your website is part of a larger solution (ie other projects such as Business Objects), or you have more than one developer, or you are actually using source-control, let me save you some time and recommend number 3.

  1. First open the Visual Studio 2003 Solution using 2005 and follow the steps to migrate to Framework 2.0.

  2. Then make any code changes to get it to compile

  3. Now for the tricky bit, open the <WebApplication>.csproj in NOTEPAD
    1. Add
          <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
      near <ProjectGuid>

    2. Add
      <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0\WebApplications\Microsoft.WebApplication.targets" />
      near whatever other Import elements exist near the end of the file

    3. Add this to the end of the file (you may need to update some settings)
        <ProjectExtensions>
      <VisualStudio>
      <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
      <WebProjectProperties>
      <UseIIS>False</UseIIS>
      <AutoAssignPort>True</AutoAssignPort>
      <DevelopmentServerPort>2555</DevelopmentServerPort>
      <DevelopmentServerVPath>/</DevelopmentServerVPath>
      <IISUrl>
      </IISUrl>
      <NTLMAuthentication>False</NTLMAuthentication>
      </WebProjectProperties>
      </FlavorProperties>
      </VisualStudio>
      </ProjectExtensions>
      </Project>



  4. If you left the Solution open while editing, Visual Studio will detect the changes and offer to re-load. The first thing you should notice is the little 'world' in the Project icon (instead of the class-library square). The Project-Properties will also have a [Web] item, and all the benefits of ASP.NET Design-time, etc should be available.



Oh, and don't forget, if IIS is still pointing at the site's directory, you need to map the Framework 2.0 Handlers to it, using the Command Prompt...
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -s W3SVC/1/ROOT

Friday, 2 June 2006

ILMerge is my 'tool of the week'

I've already been using ILMerge to merge output from a number of different projects in a solution into a single EXE or DLL for redistribution (or inclusion in other projects). It works fantastically, particularly via an ILMerge NAnt Task.

There are a few tricks, like remembering that Type info includes the assembly name! If you're directly referring to a Type in code, or a .config file, those references MUST CHANGE if that Type is subsequently merged into a 'new' assembly with ILMerge.

That's pretty basic stuff thought. Both
K. Scott Allen: Using MSBuild and ILMerge to Package User Controls For Reuse
and
David Ebbo : Turning an ascx user control into a redistributable custom control describe another interesting use : packaging up ASCX-type User Controls into redistributable DLLs. Great idea if you find building User Controls with a Design surface to be much easier than programmatically building Server Controls.

Seems like 2.0 has plenty of cool tricks to offer if you can think of them...

Friday, 26 May 2006

ASP.NET Atlas April CTP Installation Error

It was nice to know I wasn't the only one having problems installing Atlas April CTP due to cabinet file '_28942B4D9DE730210E7C27BD4FBAD377'...is corrupt.

I originally downloaded Atlas and did "Save As" (which is my habit, to install on multiple PCs). But as with quite a few others, it didn't work: "The cabinet file '_28942B4D9DE730210E7C27BD4FBAD377' required for this installation is corrupt and cannot be used. This could indicate a network error, an error reading from the CD-ROM, or a problem with this package."

I tried again, in both IE and FF, from my desktop and laptop (so four times) - clearing browser cache, etc (after the first time it broke, and I started googling for answers).

Then I noticed one of the comments on ASP.NET Atlas forum about the Publisher being 'Microsoft' versus 'Unknown', and it seemed like the versions I downloaded [Save As] and 'double-clicked' on were 'Unknown Publisher.
While not believing it would work , I tried again (with IE) BUT clicked [Run] instead... and the first dialog that appeared showed Publisher: Microsoft! The install worked fine from that point.

I don't know how/why the authenticode/whatever process would be different for a saved versus 'run straight away' install^, but after four failures across browsers/pcs and one success, I'd encourage others to at least give it a go -- click [Run] when you download!

^ actually, another post makes an interesting point about the effect of security/permissions in your IE 'downloads' folder versus your /My Documents/, /Desktop/ or wherever you might be placing the file when you [Save As]. I don't know enough about it to comment - but sounds feasible...?

Wednesday, 24 May 2006

Searcharoo v3 is LIVE

Ok, maybe not ALL CAPS exciting, but a new version of my 'basic' C# search engine and web spider Searcharoo is now 'ready'.

There's a pile of stuff I still wanted to add to it: creating interfaces and plug-ins for the Word and Number Normalization, a UK/Australian version of the stemmer, at least putting the 'language/culture' into the Stop/Go/Stemmer/Stopper interfaces so they could be language-specific and a lot more. They'll all have to wait for the next version...

'Support' and 'thanks' emails trickle in fairly regularly, hopefully that will continue.

I think the old articles are still worth reading...
Searcharoo: C# File system indexer and search (version 1)
Searcharoo: C# Search Engine and Web Spider (version 2)

Friday, 31 March 2006

"Cannot find the assembly" for Binary Deserialization

I have an ASP.NET search tool which stores a data structure in the Application cache. This 'problem' relates to the next version so stay tuned for the new code.

The structure is built up via a C# class which is defined in a .CS file. It takes a while to build (it crawls the web), so I don't want the build process to be running all the time.

The .CS file is compiled and executed 'on the fly' because it is only referenced in ASPX page @PAGE SRC=""

The assembly it is compiled into therefore has a random (and different) name every time the 'web application' restarts (eg. IIS is restarted, the computer is rebooted, or ever a change to web.config). The assembly name could be anything from "udlo.dll" to "9pd_.dll".

Rather than re-build the data structure every time the 'web application' restarts, I decided to serialize it to file, and look for the file to deserialize on restart, before rebuilding.

The XML serialized file is 77Mb+. Too big. The Binary serialized file is 4Mb. Better.

Imagine my frustration when - despite all the code looking right, the ASPX kept returning this error System.Runtime.Serialization.SerializationException: Cannot find the assembly ***
where *** was always a different, random dll name (because of the dynamic compilation of @PAGE SRC="" code files).

I already had an inkling that Binary-serialized objects could only be deserialized by the same assembly that serialized them, but I wasn't really sure why. Thankfully, goxman supplied some answers on CodeProject .NET XML and SOAP Serialization Samples, Tips.
Type information is also serialized while the class is serialized enabling the class to be deserialized using the type information. Type information consists of namespace, class name, assembly name, culture information, assembly version, and public key token. As long as your deserialized class and the class that is serialized reside in the same assembly it does not cause any problem. But if the serializer is in a separate assembly, .NET cannot find your class’ type hence cannot deserialize it...
In this case we can write our own class’s binder and tell the deserialization to use our binder while looking for our classes’ types.

As you can see - this is a real problem in my scenario - every time I need to deserialize my objects, it is because the application has restarted, the code is recompiled and by definition the assembly name is different!

Thankfully the CodeProject article goes on to demonstrate how to implement System.Runtime.Serialization.SerializationBinder and attach it to formatter.Binder... and everything worked!

Friday, 24 March 2006

Searcharoo gets some use!

It's cool when you randomly stumble on other people linking back to your code... like this blog linking to a Searcharoo user,
combining Searcharoo with Lucerne.

That, plus some positive comments on the CodeProject Searcharoo article has motivated me to get working on the code again!

Thursday, 16 February 2006

WebRequest/WebResponse and saving a downloaded binary

It took waay longer than I expected to find this code on Google... Sure you can use WebClient with it's DownloadFile() method... but if you want to fiddle with timeout settings, etc. then you need to drop back to the WebRequest/WebResponse classes.

Thanks to this GoogleGroups response download binary file using c# webrequest/webresponse I was able to get it working.
WebRequest objRequest = System.Net.HttpWebRequest.Create(url);
objRequest.Timeout = 600000;
objRequest.Credentials = CredentialCache.DefaultCredentials;
WebResponse objResponse = objRequest.GetResponse();
byte[] buffer = new byte[32768];
using (Stream input = objResponse.GetResponseStream())
{
using (FileStream output = new FileStream (fileloc, FileMode.CreateNew))
{
int bytesRead;
while ( (bytesRead=input.Read (buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
}
There are all sorts of red-herrings around this task - BinarySteam, ResponseEncoding, etc... but in the end it was relatively simple.

Tuesday, 14 February 2006

SQL Server Reporting Services RS.EXE (#1)

Automating the deployment of reports (*.rdl) and data sources (*.rds) using NAnt and RS Utility (rs.exe) has been relatively straight forward. There are a few tricks, which I'll post later; but for now, the following error had me stumped for a while, and didn't return anything useful on Google.

The required field DataSource is missing from the input structure

In my case, I tracked it down to sample code I'd copied from
MSDN: ReportingService.SetReportDataSources.

I'm using VB.NET (argh!), and the dataSources array declaration in this sample code is the cause of the error.
Dim dataSources(1) As DataSource
actually creates a two-element array BUT we only set one element
dataSources[0] = ds;
so when this line executes
rs.SetReportDataSources("/SampleReports/Product Catalog", dataSources)
it is actually sending an array where the zeroth element is set to a valid object, but the first element is NULL... hence the (somewhat cryptic) "required field DataSource is missing" error.

The fix?
Dim dataSources(0) As DataSource

Sunday, 5 February 2006

JSON - Wikipedia, the free encyclopedia

Russ pointed me to JSON - JavaScript Object Notation... a Javascript 'feature' which I'd never heard of (but maybe I've seen examples of it, and not understood what they "did").

Seems a lot like the Anonymous types and Object Initializers that are mooted for C# 3.0. Sorta.

Monday, 19 December 2005

Paris, City of Light

OK, this is pretty much off any topic, but this panoramic photo Paris, City of Light, and these panoramic photos of Paris landmarks are awesome. The entire Paris Gallery will take some time to browse through...

Tuesday, 13 December 2005

[OT] Globalization

It's been a while since I've worked on i18n projects... but the whole localisation process still interests me... this blog entry caught my eye

dasBlonde: ASP.NET Localization Tools - What are you looking for? /a>

Site localization - best approach?

makes me want to get back into the multi-language space - it's such an interesting problem...

Saturday, 22 October 2005

The 'Unofficial' Tasmanian Cadbury Marathon (Glenorchy, Hobart) Page

Can't resist adding a link to my latest 'creation' : the'Unofficial' Tasmanian Cadbury Marathon (Glenorchy, Hobart) Page. No, I am NOT a graphic designer!

All going well, I'll be able to add more useful information (including neraby accomodation, after I've booked for January myself!). After that, hopefully photos & satellite info on some of the other marathons I've run...

iPod Notes

Wow, it's been a looong while between posts. Due to "work" I have hardly looked sideways at anything tech that hasn't been related to the job at hand. No more! Starting now I expect to get my hand dirty again with a number of little projects, including cooling-up my iPod(s)... p.s. i love my iPod nano!

Project uno: get my spanish study-notes onto my iPod for reading on the bus...

iPod Hardware (apple.com) links to the iPod Not Reader User Guide [PDF]

Also summarised here, MAKE ebooks for your iPod guide!.

When they're done, I'll post them on ConceptDevelopment.net

Here are some other iPod non-music downloads:

EDIT: another nice little idea is sqlTunes - an app to extract the iTunes Xml into a database so you can query it, etc...

Monday, 13 June 2005

Blog 'discovery'

Probably not since Joel on Software have I enjoyed reading a blog as much as newly discovered Fabulous Adventures In Coding by Eric Lippert.

Some of Eric's posts I've read and liked (so far):You need to read past Part Three of the High-Dimension Spaces to see (or maybe you didn't need to read that far) the relationship to business-data-models. Consider whether Google 'word searches' equate to high-dimensional space (each letter in a word could be a dimension, each word in a query, each boolean joining, etc...). What about a Customer-Product-OrderDate tuple in your data-warehouse... is that only three dimensions, or does it become n-dimensional when you expand all the attributes of each (Customer: Country, State, Postcode, Status, ...; Product: ID, Size, LaunchDate, DiscontinuedDate, Price(AtDate), ...; etc)?
Maybe I'm reading too much into it (or reading the wrong stuff into it)...

[EDIT] Another find (2 degrees of separation from Eric's blog): Scott Berkun's essays including (the only one I've read) Why smart people defend bad ideas...

Wednesday, 25 May 2005

'shortcuts'

OK, this is a super-basic one for the command prompt - to get a recursive listing of subdirectories
C:\My Folder\>dir /s /ad /b > output.txt

back to work...

Wednesday, 11 May 2005

Debugging 'old school'

This post about Script Debugging in IE prompted me to create my own little collection of links on debugging, since I find myself currently working on a project that uses 'old school' ASP and SQL written outside VisualStudio...

Most useful is this detailed instructions document [.DOC] (on gotdotnet) or this short doc.

Then there's the lower-level stuff:
Fiddler for IE allows you to record, monitor, replay and otherwise manipulate the HTTP traffic between IE and web servers.

And these IE DOM inspectors can help to debug client-side issues by letting you view IE's understanding of the Document Object Model it has rendered.

Of course Firefox already provides features and/or extensions to do these things and more!

While we're on the subject of debugging, here's a tip for SQL Debugging after XP SP2.

Tuesday, 10 May 2005

About Cassini

If you ever installed Web Matrix (0.5 or 0.6 - it will never make version 1...)
you will already know what Cassini is... a lightweight C# web server that enables ASP.NET applications to be run without IIS.

MSDN explains Client-side Hosting with Cassini and how Cassini is used in MS-CRM.

"What use is that?", you ask... well despite the fact that it appears to be just a cute open source project, Microsoft has implemented it (well, some form of it) in Visual Studio 2005 as the primary way for developers to run ASP.NET applications without having to install IIS.

You can also use it, as Scott Hanselman has, to cobble together an NUnit ASP.NET tester using Cassini...

FYI, the name "Cassini" sprung from the code name for Web Matrix (which was "Saturn")... Cassini is of course on of Saturn's moons. More code-names decoded here.

Monday, 9 May 2005

More on Ajax

Although it hasn't taken the ASP.NET world by storm (yet), the term Ajax (and the underlying javascript-xml technology) is certainly being discussed more frequently as a viable design option. Whereas previously javascript might have been ignored in favour of Validation Controls (and the occasional pop-up window), Ajax (along with 'implementations' in Gmail, Maps.Google, etc) seems to have elevated the concept of dynamic apps into acceptability.

Since the same idea will be part of ASP.NET 2.0 (Script Callback) it kinda makes sense; but thankfully you don't have to wait until then to give it a try, as quite a few resources are appearing to get you using it now:


Have fun

Sunday, 1 May 2005

Agile and Database Design

One of the least-often-mentioned aspects of Agile Development (IMO) are the challenges involved in database change management, described in Martin Fowler's
Evolutionary Database Design.

Martin states "One of the most valuable pieces of automation is a simple set of scripts for common database tasks" - but I'm not so sure that there is a simple way to accomplish all that in a foolproof manner.

It's definitely do-able in a team of disciplined developers with good SQL knowledge, experience and dedication to writing DDL, DML and understanding when they're making a destructive change. But what about teams of different skill levels (particularly in SQL), very large databases where mulitple delta-changes, when applied, will take HOURS to run (ie. longer than a maintenance window), etc...?

Not that I have a solution right now - but why isn't it a more visible "problem" - what is everyone doing to solve this problem - manual processes?????

[EDIT 9-May-05] Peter Hancock's Continuous Database Integration article describes a novel, NAnt-based approach; but it still requires a lot of 'thought' to ensure it always works...
[EDIT 15-May-05] Unit Testing the Data Access Layer covers the 'related' issue of how to test the database...

Issues with dynamically-added ASCX

Explaining to someone why dynamically added Controls (or DataGrid columns, for that matter) can't be accessed after postback can be difficult, requiring understanding of the entire page lifecycle, the difference between the 'declarative' Control-tree and the 'run-time' one, how statelessness affects the two and why Viewstate doesn't solve the problem.

Depending on what you're trying to do, there are various workarounds including accessing the Request.Form collection directly to retrieve inputs, without accessing 'the control'; however this can be fraught with INamingContainer-induced control-name issues (see Scott Watermasysk's Implementing Dynamic ItemTemplates).

This blog on Adding controls to ASP.NET page at runtime and the Dynamically Created Controls in ASP.NET helps show the correct approach - re-adding the controls to the page before accessing them.

The MSDN page An Extensive Examination of User Controls - How User Controls Are Processed also offers some useful insight, as does the Control Execution Lifecycle

IMO every ASP.NET developer should understand and be able to describe this solution, even if they can't recite the implementation specifics without a quick Google!

Wednesday, 27 April 2005

Forecasting the future...

OK, I haven't posted for a while... been busy!

Having heard (over and over) about how cool Master Pages is in ASP.NET 2.0, we got sick of waiting and are going to implement the Microsoft-published Master Pages sample from 2002. The funny thing is, I had already used that on a project way back then - but before I really fully understood the Page class and ASP.NET internals... you'll see a post of mine on that www.asp.net page - and I clearly haven't yet learned about Control.ClientID. D'oh! Removing the INamingContainer attribute seemed like a good idea at the time :)

Actually, we'll probably use the MasterPages: Improved Version by Paul Wilson anyway.

As for the post title - Paul was spot on: "MasterPages is the most flexible and easiest to use of Page Template solutions, and since it was created by Microsoft it will likely someday be in ASP.NET itself."