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."

Thursday, 24 March 2005

Ajax: Asynchronous JavaScript + XML

Dare Obasanjo's post 'responding' to an article discussing a new approach to web applications that we at Adaptive Path have been calling Ajax. The name is shorthand for Asynchronous JavaScript + XML
is a fun read. I'm not really for or against people making up buzzwords, but a common language is always useful to aid understanding, and to me Ajax (if you're aware of it) does communicate more than his suggested "instead of Ajax, 'XML and script'"... (and Robert Scoble agrees)

Anyway, I was specifically researching information about using XmlHttpRequest ? after reading about an XmlHttpValidator for ASP.NET and Script Callbacks.

Finally - here's a collection of related sample stuff:
Presentation slides on 'Chubby Clients' by Anders Noras, info on XMLHttpRequest & Ajax-Based Applications
and an ASP.NET example from 2002, long before the 'Ajax' tag was invented!

Wednesday, 2 March 2005

Netscape Version Guide and Timeline

A nice bit of history, for those who have forgotten (or never knew) what life was like before IE (before HTML tables, before graphical browsing at all -- remember Lynx?)

Netscape Version Guide and Timeline is a great little resource. Now I'm looking for similar info on Mosaic and IE...

Tuesday, 22 February 2005

ADO.NET 'reference'

OK, I admit it - I can never remember various different ADO objects/methods... sometimes I look up code I've written before, but these ADO.NET examples are a pretty good summary of the most common bits - and they're in context which is useful.

Monday, 24 January 2005

SQL Server - when STATIC is DYNAMIC

My head hurts... according to MSDN documentation on CURSORS:

“Forward-only: The rows are not retrieved from the database until they are fetched”

“Static: The complete result set of a static cursor is built in tempdb when the cursor is opened”

which seems mutually exclusive, but

“SQL Server considers both forward-only and scroll as options that can be applied to static, keyset-driven, and dynamic cursors.”

and finally

“When a database API cursor attribute or property is set to forward-only, SQL Server implements this as a forward-only dynamic cursor.”

so specifying STATIC FORWARD ONLY gets implemented as DYNAMIC FORWARD_ONLY (no tempdb)
and STATIC alone gets the tempdb copy you’re (presumably) after…

Forward-only Cursors

Static Cursors

Tuesday, 18 January 2005

John Howard, Blogger?

For those not in sunny Australia, John Howard is our very long-serving Prime Minister (yes, we're still a democracy, it just seems like he's PM for life...)

Anyway, this 'unofficial' John Howard Blog is bloody funny...

[Sorry, I'll blog something tech-related again soon...]

Tuesday, 11 January 2005

Scrolling tables, fixed headers

A common Html display problem in enterprise applications is presenting lots of tabular data. Users are 'used' to Excel tables where they can always see the column headers as they scroll down a list.

MSDN has a useful example of a scrolling table with fixed header using HTC. It's IE-specific (of course) but seems to be fairly easy to implement. This does pretty much all I need, for now.

However, ActiveWidgets Grid is an awesome Excel-like grid view with column and row headers, plus icon/tooltip support. It's "somewhat" cross browser too (IE, Mox, FF but not Opera, Safari) and if I was really wanting to impress someone this is the one I'd use. One downside is the population of the table via Javascript arrays, which I suspect makes it impossible to do rowspan/colspan tricks which I often need.

Monday, 10 January 2005

WYSIWYG Editors in DHTML

I can't count the number of projects where the user's have asked for a text-input area "just like Microsoft Word". Inevitably they also ask for some specific feature or function that means the last control I used is not quite right.

Here is a list (for future reference) of some of the open source alternatives: Open Source WYSIWYG Through-The-Web Editors.

Of course, there's always RichTextBox if you want to pay (and get support!).

p.s. blogging has slowed dramatically in this new job. Hopefully it'll be more regular in the new year!

Thursday, 30 December 2004

Asia Earthquake/Tsunami Aid...

"The Australian public can help these aid agencies reach affected people by giving much needed cash donations to purchase and deliver urgently needed supplies. In kind donations of clothing, toys, blankets and food are NOT being collected as it is expensive to transport these goods overseas and they can be purchased more cost effectively either locally or regionally."

ACFID - Asia Earthquake

How to Help

Thank you

Monday, 22 November 2004

Australiana

This is a pretty cool site for travellers and Australians...
Know Your Australia
lots information including things you might not expect - such as language, food, humour and also The Man From Snowy River and other poems by Banjo Paterson.

OK, a bit off-topic...

Tuesday, 26 October 2004

Page Inheritance In ASP.NET

Page Inheritance In ASP.NET is a favourite topic of mine, and although I've implemented a similar model to this in the past, I like how Jon's written it up.

Sunday, 24 October 2004

C# "using" Tricks

Interesting idea from whatever: Stupid "using" Tricks -- scroll down to WriteEndElement and the discussion on writing xmlWriter...

Xml Sucks...

Well, not really - but some people obviously think XML has some serious deficiencies.

Came across that link - a long read but interesting points-of-view - while searching for info on the iTunes (rocks!) Music Library XML file. I want to move info between two installs of iTunes (song ratings, # plays, etc) and thought hacking the XML file would be fairly easy. However, the XML file itself it weird and not what you'd expect from a semantically-rich XML syntax.
<plist version="1.0">
<dict>
<key>Major Version</key><integer>1</integer>
<key>Minor Version</key><integer>1</integer>
<key>Application Version</key><string>4.6</string>
<key>Music Folder</key><string>file://localhost/F:/My%20iTunes/</string>
<key>Library Persistent ID</key><string>037D341EA9748F0D</string>
<key>Tracks</key>
<dict>
<key>136</key>
<dict>
<key>Track ID</key><integer>136</integer>
<key>Name</key><string>Evolution (Intro)</string>
<key>Artist</key><string>Bliss n Esso</string>
<key>Album</key><string>Flowers In The Pavement</string>
<key>Genre</key><string>Hip-Hop</string>
etc...

My first impression was that it was a pretty crappy XML implementation... so I jumped onto Google to see what others thought.

This article Playlist to XML had an interesting comment by Bob Ippolito:

>>"The plist format is nasty, whoever designed it really didn't know anything about XML."
>That's just totally wrong. XML Property Lists are a very unambiguous and simple serialization format. They're designed to be extremely simple and fast to parse (no attributes, etc.) because they're ubiquitous in OS X.
So maybe I was being too harsh on the format -- never jump to conclusions or make assumptions about technology! Try to anticipate the creator's goals rather than dumping on something because it doesn't fulfil yours. Here's Apple's doco fyi.

Anyway, the same blog has some useful code for transforming the iTunes format : Cleaning up iTunes plist XML. It's not quite what I want... but will get to that another time.

Tuesday, 19 October 2004

On NHibernate...

Object-relational modelling is an interesting topic - but it just seems so different/foreign that it's hard to know where to start.

It's helpful to read positive comments like these article: NHibernate and NHibernate Part Two, but there are soe many other options, like NPersist and many others...

Paul Wilson has a lot to say on Examples of O/R Mapping vs Stored Procedures

Anyway, eventually we'll get around to implementing something... somewhere...

SOT: The REAL Reason Behind the ObjectSpaces Furor

Open Lucene.NET

Wow - I didn't know that Lucene.net "disappeared" from SourceForge (wonder if selling it will work?)... to be recently replaced by Open Lucene.NET - The Open Source Search Engine.

Thanks Scott.

Tuesday, 12 October 2004

VB.NET and C# syntatic diffs

Although I will always use C# by choice, I'm currently using the (better than nothing) tool ANTS.Load which uses VisualBasic for Applications 'automation'...

So, what's a C# programmer to do? Use this handy
VB.NET and C# Comparison

BUT what is VB for the C# @"literal string" ????

Sunday, 10 October 2004

"Unable to Start Debugging" with VisualStudio web project

I much prefer Asp.net without web projects but setting it up on a new PC resulted in the dreaded "Unable to Start Debugging" message when I hit F5.

This MSDN article PRB: "Unable to Start Debugging" is NOT the problem in many cases.

It could also be that the site/virtual directory you are attempting to debug is using a different version of the framework than your app (eg. 1.0, 1.1 or 2.0) and requires you to run ASPNET_REGIIS.exe

Or it might be IIS authentication settings...

BUT for me, today, the problem was that my site (using 'Local', not 'Web Project' settings) did not have a web.config file. Simply adding a web.config file fixed the problem (all the above settings already being correct). A 'Web Project' would automatically have a web.config file included, but creating and converting a 'Class Library' to a website did not... Oops!

Monday, 6 September 2004

'Architecture' articles

OK, so I got flamed a bit for sending around this article - .NET Architecture Center: : Secrets of Great Architects. Yes, you have to (try and) ignore the gung-ho Microsoft-speak about "being a *great* architect" but the fundamentals are all there.

Possibly this is a better article Realizing a Service-Oriented Architecture with .NET - it's shorter, easier to read and the pictures make more sense. The scope is a litter narrower, but still a useful read for anyone who thinks 'architecture' is only for buildings.

This info on Developing Identity-Aware ASP.NET Applications is useful and "also provides detailed prescriptive guidance for implementing intranet and extranet ASP.NET applications that are integrated with Active Directory."

Wednesday, 1 September 2004

Localization Resources with ASP.NET 2.0

Two CodeProject articles on Creating multilingual websites are great sources of information, and actually mirror the way I've also approached the problem with my own projects.

But something I hadn't read much about (yet) is Using Resources for Localization with ASP.NET 2.0 (Fredrik Normén's) which was linked from CodeProject. The approach in ASP.NET 2.0 still seems a bit clumsy to me - still no "built in" way to have site-wide localization management, nor a simple cross-over between localization of static elements (such as labels, text, html elements) and database-resident information (product names, news items, etc). You could argue that there are a multitude of possibilities and that Microsoft can't address all possible permutations -- but why not at least offer a basic solution, like they do for Authentication, Personalization, MasterPages, etc???

Monday, 16 August 2004

About the Provider Model...

I'm planning to use the Provider pattern to abstract implementation details in my search-engine project (Searcharoo), so I'm always interested to read about it. Another search project - Nata1 has implemented the pattern, although I haven't looked at what they've done.

Provider Model Misconceptions is a useful resource that discusses some of the concepts.

Oh, don't forget Part 2 of the MS pattern article.

Wednesday, 11 August 2004

IIS Cache-control: private

Interesting question today: IIS sets a default
cache-control: private header for ASP and ASPX requests which Microsoft justifies by saying that "dynamically generated pages aren't normally expected to be cached"... but where is this value _set_ in IIS and can it be easily turned off without asp/x code or ADSI script???

This MSDN article on CustomControlCache in the metabase explains how to set CacheControlCustom = "no-cache" but I cannot find it 'pre-set' anywhere in the metabase as a default value.

This sounds like it will work for .swf and other custom MIME types that you might want to set specific cache policies for, but it's very dodgy; appending a CRLF and 'fake' cache-control header to the content-type sent by IIS... surely this would 'break' if a cache-control: header was also sent another way (such as 'cachecontrolcustom' above) - would result in two possibly conflicting headers...

There's also this information Microsoft IIS 5.0: IIS Optimization and the Metabase but it's not that useful either...

Wednesday, 4 August 2004

Using XML in Localization

I will never understand why a company that owns translate.com calls itself "Enlaso"... but they have some interesting content on their website, including
Using XML in Localization.

The Rainbow tools might also be useful, offering simple encoding conversions, line-break conversion, RTF processing and other utilities... although I haven't tried them out myself (yet)

While we're talking about XML and L10n, Xliff is my favourite standard right now.

Tuesday, 3 August 2004

c# Enums

Enums are a very useful way to improve code readability, speed-up coding (think intellisense autocomplete) and enforce business rules... but there are also niggly little issues like having to figure out the Enum.Parse method and how to AND/OR Enums together using the [Flags] attribute.

Thankfully, here's a very useful post of links to all sorts of Enum-related info
Enums + Attributes = Swiss Army Knife

And a very useful sample lives here Associating string values to items in code with code.

Decorating Enums with string attributes sounds like it could be used to solve two ongoing problems:
  • localizing(translating) the meaning of an Enum for display to a user, maybe using some sort of 'translation key' attribute; and
  • linking the Enum type to some underlying database lookup table to which it is related...

Thursday, 29 July 2004

String.Format("{0}", "formatting string"};

I can never remember all the options for string formatting, particularly the ability to 'pad' strings - in the past I've written padding methods in C# because I didn't know about the format specifier!

idunno.org: String.Format("{0}", "formatting string"}; has a good reference for the most common format specifiers...

idunno.org also has a good reference for accessing IndexServer from .NET.

Sunday, 18 July 2004

ASP.NET HtmlControls vs WebControls

One of my 'standard' questions when interviewing for ASP.NET Developer roles is What is the difference between HtmlControls and WebControls?
I have not yet received a really good answer from any candidate, and I've been using this question for over 18 months in a number of interviews... I've just finished another round of interviews and haven't found much understanding of this stuff!

These two articles go some way towards explaining the issues:
What I want to hear is:

  • With HtmlControls, you *know* what the output will look like at design time (basically what you've typed, with the runat="server" gone)

  • The HtmlControl.HtmlGenericControl is the *only* way to accomplish some things neatly like manipulating the TITLE, META and other tags

  • WebControls have a 'consistent' object model (ie. they all have a .Text property, whereas HtmlControls might require using .Value or .InnerHtml)

  • WebControls *may* be rendered differently depending on their attributes OR the BrowserCaps of the browser. Eg. an asp:TextBox might be rendered as an INPUT or TEXTAREA if TextMode="mulitline"; the Date Picker will be drastically different on up- and down-level browsers


Things I don't want to hear are: HtmlControls don't run on the server, HtmlControls don't have ViewState support, HtmlControls are somehow less useful, confusing HtmlControls with non-runat=server Html tags in the source.

If you've done any Mobile development then it might help if you know how the BroswerCaps works to render cHTML/WML/etc on different devices...

Bonus points for: Mentioning the INPUT TYPE=FILE HtmlControl and how it works when run as an HtmlControl, mentioning the asp:Literal control and how all 'static' text between Server Controls on a page becomes an instance of the Literal control during page parsing, mentioning the more complex WebControls such as Date Picker and the Validation controls.

You're hired if: you can explain what happens when WebControls are rendered on up- and down-level browsers; you can explain the barriers to the WebControls being rendered as up-level on non-IE browsers, the issues with the Validation controls in thisi scenario and how to fix them; and you know why these two namespaces are significant for control rendering System.Web.HttpBrowserCapabilities and System.Web.Mobile.MobileCapabilities...

I wonder how many candidates 'Google' their prospective employers/interviewers...

UPDATE: words to avoid in your resume

Saturday, 17 July 2004

"Universal" or "Neutral" Spanish Translations

There's always something new to learn about software localization - for instance
Microsoft's approach to creating "Universal" or "Neutral" Spanish Translations.

I suppose if you asked the 'person on the street' they might think there _is_ only one Spanish (or French, for example) language - at the other extreme if you asked a Mexican, Bolivian (or New Caledonian/French Canadian) they would probably insist their native tongue is quite distinct from that used in Spain (or France).

When faced with localization in these languages, the two obvious solutions might be:
* use the 'original' language and expect it to work in all other countries; or
* localize into each and every 'dialect' of the language to ensure you do not alienate customers in each country.

The (think outside the square) solution is, of course, to merge these two ideas -- purposefully structure the language you use so that it appears natural to ALL speakers. That's actually a lot harder than it sounds, but reducing the number of software versions you have to ship from ten to one (eg. in Spanish) certainly appears to make it worthwhile. This i18nguy article about Microsoft discusses the concept of “Universal” or “Neutral” Spanish and particularly Latin American Spanish (es-americas).

Thursday, 15 July 2004

MS: Hazards of Hiring

The Hazards of Hiring is the last topic I expect to read about on MSDN -- but relevant since I'm hiring at the moment.

The other article I found useful was the Guerrilla Guide to Interviewing, which I may have blogged previously (but it's worth another look).

UPDATE [7-Sep] WHY is it that candidates no longer feel any compulsion to do any research on a company before attending an interview. My first question is always "What have you learned about our company?" or "Did you review our website?" -- the answers to which are inevitably "No..." Why waste your time (and mine) by turning up to an interview where you don't even understand what our company does? This laziness is so common that it's ceased to be a useful measure of a candidate's interest in a position, because NONE of them bother to do it!

Wednesday, 7 July 2004

Character-set/encoding detection using C# - NCharDet

NCharDet is a C# port of the Java JCharDet, which is based on C++ code used in the Mozilla open-source browser project.

I don't yet fully understand the implications of the Netscape Public Licence so the code is just posted on my website for now.

I was disappointed that I couldn't find info on this already available on the web - particularly that no-one seems to have got MLang.dll running under COM Interop with C#/.NET...

Saturday, 3 July 2004

Populating a Search Engine with a C# Spider on [The Code Project]

My two Searcharoo search engine articles are now also available on The Code Project

as well as on my personal website... a friend suggested they might get better coverage there - and so far a couple of very useful comments, so it was a good idea!


ALSO I just came across an excellent article about Integrating Unit Testing into the Software Development Lifecycle - check it out.

AND FINALLY, this is also a great post/book review of Debugging the Development Process by Steve Maguire. Even if you don't read the book - READ THE POST.