Lee Kelleher’s Weblog

Just another WordPress.com weblog

Setting up Visual Studio to work with Umbraco

with 2 comments

Over the last 12 months I have been involved with developing several Umbraco-powered websites. During that time I’ve experienced many development frustrations; specifically with debugging and version control.

A while back I read Paul Sterling’s blog post on “Working with Umbraco in Visual Studio” - I used this as my basis.  I have added to his orignal suggestions:

  1. Have a clean, working copy of Umbraco - using the installer - on your machine.  I am using: C:\inetpub\wwwroot\umbraco\ for my working copy of the site.
  2. My Visual Studio solution/project will be kept under version-control.  Since I use Subversion, (with TortoiseSVN and VisualSVN), I prefer to keep all my code under: C:\SVN\
  3. In the Visual Studio project, I create the following folders:
    1. /_templates
    2. /css
    3. /scripts
    4. /usercontrols
    5. /xslt

    These folders reflect the files that will be used in my Umbraco site.  The “/_templates” folder is used to store a text-based version of Umbraco templates, so that I can keep them under version-control; as I’ve had a situation in the past where someone copied over the wrong template - not very pretty.

  4. In Visual Studio, create a post-build event [from Project > Properties > Build Events] to copy all your working files across to your Umbraco installation.
    XCOPY "$(ProjectDir)bin\$(ProjectName)*.*" "C:\Inetpub\wwwroot\umbraco\bin\" /y
    XCOPY "$(ProjectDir)usercontrols\*.ascx" "C:\Inetpub\wwwroot\umbraco\usercontrols\" /y
    XCOPY "$(ProjectDir)xslt\*.xslt" "C:\Inetpub\wwwroot\umbraco\xslt\" /y
    XCOPY "$(ProjectDir)scripts\*.js" "C:\Inetpub\wwwroot\umbraco\scripts\" /y
    

    You may notice that I am not copying across the *.css stylesheet files across to Umbraco.  The reason for this is that the current version of Umbraco (v3.0.3) stores the contents of the CSS files in the database, and not on the file-system.

    You can either set the “Run the post-build event” whichever option you prefer.

  5. Once your files have been copied across to Umbraco, you can debug your code in Visual Studio:
    1. Open the site (usually http://localhost/) in your web-browser.
    2. In Visual Studio select the Debug > Attach to Process menu.
    3. Select the ASP.NET worker process from the list - this is usually called “aspnet_wp.exe” or “w3wp.exe” - then press OK.

It’s important to note that I am developing on Visual Studio 2008; but the same prinicple should apply to VS.NET 2005. (Update: It isn’t so straight-forward in VS.NET 2005, see Brad’s comment for further details.)

I’m still looking at ways to improve my development set-up with Umbraco/Visual Studio, so if anyone has any tips - please pass them my way!  I’m especially interested in ways of dynamically updating the stylesheets/templates via the Umbraco API.

Written by Lee Kelleher

August 20, 2008 at 6:17 pm

Posted in blog

Tagged with , , , ,

My WordPress hacked by c99madshell script

with 6 comments

After all the excitement of last Friday’s attempted hack on my travelblog, and the subsequent upgrade to WordPress 2.6 - I thought everything was under control.  Boy was I wrong!

A few hours ago I received a blog comment (from a Mr Andrew Wong) on the travelblog:

http://www.lee-and-lucy.com/travelblog/index.php?p=5817
check this out!!

I clicked the link, my jaw dropped!  It wasn’t an attempted hack, it was a very successful hack… I felt violated -in a digital sense.  The threat was far from over!

From looking through the WordPress management screens, I couldn’t find a blog post with the ID #5817.  I opened up phpMyAdmin to see if it was in the database; nope, nada, nothing!

I wanted to see the extend of the problem, so I googled “site:lee-and-lucy.com“, and found a “lot” of pages… oh yes, LOTS OF SPAM!

To say the least, I was furious!  I wanted to; a. resolve this asap; b. find out how this happened; c. cause pain to this would-be hacker!  Obviously, option c. goes against my good karma nature, but they digitally violated my site; sticking spam in places that spam should never go!!! Furious I tell you!

Digging through my WordPress files, I find a PHP script in my theme folder called “simple.php“; it contains a nested “eval(gzinflate(base64_encode()))” string.  Very suspect. I try to manually decrypt the string, (replacing the eval with an echo), but it’s nested a few levels deep… so I found a snippet of code that would easily decode/decrypt it.

The script turned out to be a modified version of c99madshell, specifically focused on WordPress hi-jacks.  The script tries to inject a small trojan code into one of the core WP files (for me it was the “wp-blog-header.php“).  I removed the hi-jacked code, along with the “simple.php” file (from my theme folder) - then re-upgraded to the latest WordPress (2.6) … just to overwrite any other tampered files.

Hopefully this should be the end of this matter (until next time) ….  I’ll be keeping a careful eye on my WordPress installations now on.

Written by Lee Kelleher

July 22, 2008 at 12:35 am

Hindsight… It’s is a wonderful thing!

with 2 comments

A couple of hours ago I received an automated email from our Travelblog site, saying that we had a new user registration; which was strange, since we disabled that feature a long time ago!  Great! We’ve just been hacked!

I put my hands up in the air, I’d been running an old version of WordPress (2.2) … which I’ve been meaning to upgrade for a long time; but hey, I’ve bought a house, had a baby and build my business during that time! It’s not been at the top of my priories.  So yes, I’m aware of the security holes/risks, etc.

Needless to say, WordPress 2.2 has an ugly security hole which allows hackers to remotely inject SQL statements into the database.  I’d heard about this at the time, but thought I was covered because it relied on the hacker having a valid username/password (see the trac ticket). Well it seems they don’t!

Within a minute of receiving the new user registration email, I deleted the user account, changed our passwords and upgraded to WordPress 2.6 - which came with it’s own set of problems (i.e. all the category names disappeared).

Here are the details of the would-be hacker, so others know about him:

Username: sidon
E-mail: Dimka@hotmail.com

Written by Lee Kelleher

July 18, 2008 at 11:02 pm

Posted in blog

Tagged with , , ,

How to prevent hotlinking to FLV files? (Flash Videos)

with 2 comments

My friend Shane (from DVD House of Horrors) is having a hard time trying to stop other websites hotlinking to his horror movie clips.  The site is running Joomla on a Linux server, so he’s been down the usual .htaccess routes to prevent remote hotlinking.

However the problem with FLV files is that they aren’t requested directly by the web-browser, but rather the Flash video player (a .swf file).  This causes a problem for the .htacces rules as there is no HTTP_REFERER value to restrict against.

This is causing an unnecessary hit on Shane’s bandwidth costs… so he’s desperately looking for an answer.

Any ideas are most welcome. Thanks.

Update: It seems that a lot of people have this same problem… so I suggested to Shane to turn the situation around by using the hotlinking as an advert for his site.  All his video clips are watermarked with the DVD House of Horrors logo.

I’m curious why the developers of the Flash video players don’t send a HTTP_REFERER value, but then again that’s also easy to spoof.

Written by Lee Kelleher

July 2, 2008 at 1:07 pm

Posted in blog

Tagged with , , , ,

.NET Test-Driven Development

with 5 comments

Has anyone got any pointers on how I should start doing test-driven development in .NET?

It’s something I’ve been meaning to look into for years now.  I’ve got all the usual Visual Studio add-ons installed… NUnit, TestDriven.NET, etc.  But no idea how to use them!

Usually I learn this stuff on the job, yet from most other developers I speak to - it’s all guess-work!

Any advice is much appreciated!

Written by Lee Kelleher

July 2, 2008 at 1:43 am

Posted in blog

Tagged with , , ,

Last.fm Web Services

leave a comment »

Last.fm Last weekend, the good folk at Last.fm revealed version 2.0 of their public API:

The new API introduces a user authentication protocol which for the first time allows applications to create user sessions, bringing both read and write services to web apps, desktop apps and mobile devices.

Take our new tagging API’s. Developers can both pull and apply tags to music content from any application on any platform now. The same goes for sharing – developers can build Last.fm sharing support into any app.

There are also new search, playlist, event and geo API’s being rolled out today, with lots more stuff planned in the coming weeks and months.

At first glance, I noticed that there were a couple of key features (to me) were missing - namely the “Get Similar Tracks” - the Last.fm staff reminded me that they are planning to roll out more features in the coming weeks and months! OK, okay… I’ll be more patient!

The new API feels and works like the Flickr API; with very similar convensions of the method/call names and authentication/token process.  This isn’t a bad thing - just that I feel they should be leading the crowd, rather than following it.  (The beta version of the upcoming Last.fm site is being critisised for being a “facebook clone”!)

Regardless of my negative comments, I’m actually a fan of the new API - being more structured and scalable.  I’m considering writing a .NET wrapper library (C#) for it too!  As I’ve got plans for a small iTunes/Last.fm playlist app, that would require it; (all open-source, of course).

Since the new API follows similar Flickr API convensions, it seems to make sense that I could/should base my Last.fm .NET wrapper on it’s Flickr counter-part…. Flickr.NET API.  The library is developed in a decent way - deserializing XML objects into the appropriate classes.  It feels a lot nicer to develop with, rather than messing around with XPath node selections!

Not sure when I’ll get the time to develop the library, as my contract work is as busy as ever!! Hopefully things will calm down in a couple of weeks!

Written by Lee Kelleher

July 2, 2008 at 1:29 am

Posted in blog

Tagged with , , , , ,

Firefox 3 - Download Day

leave a comment »

Download Day

Today is Firefox 3 Download Day! Mozilla are hoping to set a Guinness World Record for most software downloads in 24 hours.

At the time of writing, over 1.2 million people have pledged to download Firefox 3 on the Download Day!

This is a first attempt of this record, so there is no number to beat. But Mozilla want to outdo the number of Firefox 2 downloads on its launch day, which was 1.6 million! The aim is 5 million+!

Download Day 2008

Update: It’s official, Firefox 3 set a Guinness World Record for the most software downloads in 24 hours. Reaching 8,002,530 downloads! They even give me a certificate for taking part … feels like I’m back at primary school! :-D (so proud!)

Written by Lee Kelleher

June 17, 2008 at 12:01 am

How to best embed a WMV video clip?

with 4 comments

I hate to admit it, but I’m stuck… I’m trying to figure out how to best embed a WMV video clip in a web-page, so that it works cross-browser (and cross-platform).

Even after all my years of web-development, I’m still confused to which browser supports which tag … nested <embed> tags in <object> tags … it gets messy!

I’m as equally confused with the Class ID attribute: “CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6” - surely that can’t be the same across all browsers/platforms?!

A List Apart article discusses dropping the <embed> tag. Which sounds like a good idea to me. The HTML looks so much better… MIME types all the way baby!!


<object type="video/x-ms-wmv" data="/media/video.wmv" width="320" height="260">
	<param name="src" value="/media/video.wmv" />
	<param name="autostart" value="0" />
	<param name="controller" value="1" />
</object>

I tested this on Firefox 2.0 and IE7 on Vista, and IE6 and Safari on XP - all fine, so far so good! When I ask my client to test the page on their Mac … it’s no good! The videos just wouldn’t load! Hmphf!

So does anyone know of a simple way of embedding a WMV video clip that works cross-browser/platform? Please let me know, I’d be very a happy developer!

Otherwise, I’m so close to using the beastly code that comes from the “Embedded Media HTML Generator” … help me please! ;-)

Written by Lee Kelleher

June 9, 2008 at 2:56 pm

Posted in blog

Tagged with , , , , , ,

How to convert NameValueCollection to a (Query) String

with 5 comments

Most ASP.NET developers know that you can get a key/value pair string from the Request.QueryString object (via the .ToString() method). However that functionality isn’t the same for a generic NameValueCollection object (of which Request.QueryString is derived from).

So how do you take a NameValueCollection object and get a nicely formatted key/value pair string? (i.e. “key1=value1&key2=value2“) … Here’s a method I wrote a while ago:

/// <summary>
/// Constructs a QueryString (string).
/// Consider this method to be the opposite of "System.Web.HttpUtility.ParseQueryString"
/// </summary>
/// <param name="nvc">NameValueCollection</param>
/// <returns>String</returns>
public static String ConstructQueryString(NameValueCollection parameters)
{
	List<String> items = new List<String>();

	foreach (String name in parameters)
		items.Add(String.Concat(name, "=", System.Web.HttpUtility.UrlEncode(parameters[name])));

	return String.Join("&", items.ToArray());
}

Just in case you didn’t know about the System.Web.HttpUtility.ParseQueryString method, it’s a quick way of converting a query (key/value pairs) string back into a NameValueCollection.

Written by Lee Kelleher

June 6, 2008 at 1:22 pm

Posted in blog

Tagged with , , , ,

Making Request.QueryString writable (by clone/copy)

leave a comment »

Every now and then I completely forget that the Request.QueryString (and Request.Form) object is read-only. Today I had a bit of functionality where I needed to remove a key/value from the collection - but the Remove() method (of the NameValueCollection object) throws an exception.

Unfortunately, the Request.QueryString’s CopyTo method assigns the values to an ARRAY, not a NameValueCollection - losing functionality and flexibility.

You need to copy the Request.QueryString object to a new NameValueCollection instance, here’s how:

NameValueCollection qs = new NameValueCollection(Request.QueryString);

Now you can add/remove the key/values to your hearts content!

Oh, yeah, remember to import the System.Collections.Specialized namespace too!

Written by Lee Kelleher

June 6, 2008 at 1:09 pm

Posted in blog

Tagged with , , , ,