Imagine a scenario where you have around 100 ASP.NET web sites all using the same code base, which each consume site specific data from the same database and have several thousand dynamic pages each! Sounds daunting doesn’t it? Once you have all these sites configured that is ok for the time being, but what happens if you want to update all of these sites with a new version of the code? Some of you will already be shouting bad architecture, but if if a client wants dedicated IP addresses for each site and you intend to do caching in any meaningful way then separate sites with separate resources on potentially different web servers and even on different hosting companies does make some sense.
I first looked into using an FTP library like:
http://www.codeproject.com/KB/IP/ftplib.aspx but soon realized that any hand rolled application would need to be robust enough to handle connection problems and update failures etc. It was then that I realized I already owned a tool that could with a little effort take care of the job.
WS_FTP Professional
With any tool there is certainly going to be some setup required and to make this solution work I did in fact create all 100 or so sites in the WS_FTP GUI, while you can save a sites individual ftp settings within the Visual Studio IDE it certainly cannot handle the scenario I am describing in this post. The cool thing about
WS_FTP Professional is that it ships with a scripting tool and is also a great way to manage a myriad of FTP connections and allows you to name them and group them into appropriate categories of your choosing. The scripting language itself is also easy to use (and remember) and is very powerful. Obviously once you create a script you can save it and also use the WS_FTP scheduler to run scripts at convenient times (in the middle of the night to cause the least disruption!)
A simple example:
CONNECT "My Sites!Mysitename.info"
LCD “C://NewFiles”
CD “bin”
RDEL “*”
RPUT “*”
CLOSE
Here the script simply connects to a site in the My Sites group (think of the exclamation mark as a /), navigates to the folder locally where the new files are located, navigates to the bin folder of the remote site, deletes the contents, uploads the new files and finally closes the connection.
This is a simple example but you can target specific files and navigate folders during the same session, you can also download files. Even so writing a 100 of these for a single update is still a little annoying and sadly there is no for each loop to iterate through the sites in the "My Sites Group" part in the scripting language. What worked for me was to write a small Winforms app which helps me write the scripts using placeholders. This application reads the site names from a small data store and uses syntax like:
CONNECT “#SiteName#”
LCD “#LocalSiteFolder#”
DEL “web.config”
PUT “web.config”
CLOSE
When I click the go button in the Winform, the application generates a script for each of the sites, replacing the placeholders (e.g. #SiteName#) with the appropriate text. This works well too if, as in my scenario, the web.config file for each site has site specific settings, so in the example above I am able to target the folder for that specific site (which contains site specific files) and specify a file in it (this also works well for CSS files as each site has it's own theme).
All I need do is save the script and schedule it to run or simply paste it directly into the WS_FTP scripting utility and let it go about it's business. The
WS_FTP Scripting Tool also has a log panel, so you can see if an update has failed for whatever reason.
As you can see with a little effort and the right tool you can turn a maintenance nightmare into a relatively painless exercise.
[edit 1st Feb 2010] Still available[/edit]
If a 10% ReSharper rebate discount code and a 60 day extended trial wasn’t enough! For a limited time only, if you purchase ReSharper 4.5 now (after October 15th, 2009), you can receive a free upgrade to version 5.0
To take advantage of this offer and to receive a 60 day extended trial license and 10% ReSharper discount coupon, please email me at:
web2asp@live.comI completely respect your privacy so your email address will ONLY be used to send you the details and NOTHING else.

Hot on the heels of ASP.NET MVC 2 preview 1, released a mere 2 months ago (great work MS that’s agile as hell), Phil Haack announced yesterday that ASP.NET MVC 2 Preview 2 is now ready for download! you can get yours here:
ASP.NET MVC 2 Preview 2 Download
For those of you familiar with Preview 1, where the focus was primarily on data annotation, Preview 2 builds heavily on this, with the addition and inclusion of client-side validation via the JQuery validation library. Although users of other libraries need not flinch! You can easily write a client adapter for the JSON Metadata, so you are not chained to the JQuery validation library by any means.
My personal favorite is the addition of Single Project Areas, which essentially means that you can divide out your MVC application pretty much how you would like, without having to have multiple projects. With this preview the registration of Areas has also been simplified, so it works real nice with little effort.
VS2010 users should be aware that the tools for Preview 2 only work with VS2008 SP1 so you will need to wait for beta 2 before you will be able to try out HtmlEncoding code blocks and the like.
I still think it is a crying shame Rob Conery has left the Microsoft fold it would be SERIOUSLY great to have subsonic integrated totally into the MVC framework and an integral part of VS2010. That’s just my 2 cents worth!