Author: Sam Stephens

I improved an implementation of a table in which each row is clickable to toggle the visibility of a detail row below it. The previous implementation gave each row a numbered id, and applied a separate onClick function to each row. I realised a more efficient approach would be to apply appropriate classes to the table, and use a function that runs across the table and applies the appropriate event handlers.

The table is structured approximately like this (I’ve left out a header row and other complications).

Each summary row of the table has the class summary. The class hide is used to hide the details row – all the details rows start with this class set. When a summary row is clicked the first time, the class selected is applied to that row, and the class hide removed from its detail row (the row below it). When the row is clicked again, the class selected is removed from that row, and the class hide applied to the detail row.

I’ve seen people saying things like “why use jQuery, when you can just use javascript”, and as javascript support gets more mature, this is a fair point. For me, the simplicity and ease of jQuery style coding appeals – I especially enjoy the way function calls are chained.

The next challenge was a change request to add an Expand All button to the header above the table. The markup is approximately like

In the selector to find the Expand All control, $(tableSelector).prevAll(headingSelector).find(expandAllSelector), I use prevAll because the header is not always the element immediately before the table. It’s pretty easy to see what’s going on. If an Expand All element is found, its click event is wired up.

On a click, the event handler works out if the Expand All control is currently open, updates its CSS class and text accordingly, and then selects or unselects all the summary rows as appropriate. The only bit of this code I don’t really like is having the text “Collapse all” and “Expand all” hardwired into the javascript. If I did this now, I’d consider attaching the text using HTML 5 data attributes, or find some similar scheme to include the text in the HTML of the table and header.

So the next time you’re looking at adding some javascript to a certain type of element on a page, rather than individually wiring up the elements, consider if you can apply an approach like this, where you add behaviour to elements that match a certain CSS selector. It’s much easier to understand, and makes for a better experience for your website users. Rather than lots of javascript being generated everytime your page is loaded, you can include the javascript in your common javascript file. The common javascript file will be cached, and only a small piece of javascript to run your function will be needed for each page. And rather than having javascript scattered throughout the pages of your site, it lives in a centralised location.

I was involved in changing an existing web application to be packaged by MSDeploy recently.

The package had to include files from external directories, as there are images, CSS and Javascript files that come outside the web application project. I needed to work out how to do this with MSDeploy.

Edit: CopyAllFilesToSingleFolderForPackageDependsOn has been renamed to CopyAllFilesToSingleFolderForMsdeployDependsOn in Visual Studio 2012. Thanks to Scott Stafford for pointing this out in his comment on the post.

This is very similar what Sayed does, except I have two targets defined in here. DefineCustomFiles creates an ItemGroup containing the files to be copied, and is defined in each project. An example looks like this.

This looks very simple, but the combination of @ and % syntax was the hard part of the exercise. I couldn’t use <FilesForPackagingFromProject Include="%(CustomFiles.Identity)"> as per Sayed’s example; using the Identity metadata prevents access to the Dir metadata previously defined to specify the destination. I ended up needing to use Include="@(CustomFilesToInclude)" so I could access the metadata. It took some more trial and error to find the correct syntax to reference the metadata of each of the items of CustomFilesToInclude, using the % syntax as shown.

I then extended the CustomCollectFiles task to check for files that already existed in the target directory.

You can see how the syntax I use in the Condition of the Error is the same as the syntax used in the DestinationRelativePath relative path above.

I toyed with the idea of adding another piece of metadata to the items within CustomFilesToInclude to indicate whether the Exists check is applicable for that item or not. But after a little experimentation I decided it was simpler to use two item groups. Any items that do not require the check go into CustomFilesToIncludeSkipExistingCheck.

So at the end of this journey I have learnt a few things: Sayed is always your first resource to search if you have MSBuild questions; the MSDeploy pipeline is extensible in a useful fashion; MSBuild can be devilishly confusing and take a fair amount of trial and error for those who don’t intimately understand it, especially when you try and do anything complex with groups of files.

To use MSDeploy’s extensibility, you need to use MSBuild. However, when not using MSDeploy, I’d like to avoid MSBuild. So the next time I start a project that promises to have any complexity, I’ll be looking for a build framework that makes it easy to leave complex behaviour outside of MSBuild. I investigated psake after seeing that Rhino.Mocks uses it, and liked what I saw. I also like that you don’t have to learn a specific “make” language – psake’s decision to leverage an existing scripting language is smart and practical.

I’ve just had to analyse a bunch of Event Logs that contain exceptions, produced from a load testing exercise. I needed to turn them into a summary of the counts of each class of exception that occurred.

The exceptions belonging to each class of exception message didn’t generate exactly the same text in the event log data every time. So I decided the simplest way to categorise them was to have each category able to work out if it matches event log data using one of two criteria: either data contains a substring; or data matches a Regex. Flexible enough for the fairly simple requirements of this scenario.

After a little research, I found out about the existence of the System.Diagnostics.Eventing.Reader class, which will parse event logs from either the local or a remote computer, or from an EVTX file. The event logs I was parsing already needed to be saved into a file and archived after each run, so I made the parser use the archived files. I’m still keen to play with parsing logs directly off remote computers at some point.

Here’s some code. I haven’t included all the boring declaration of constants and the like in these code snippets, just the interesting bits. Some of it’s a wee bit hack-ish and not properly structured or parameterised; as this is a small utility for occasional use, the effort to make it really nice isn’t currently justified.

Next time around I’d look at Powershell to do this: Get-EventLog also looks like a simple way to deal with event logs. But I’m glad to have had the opportunity to learn about System.Diagnostics.Eventing.Reader.