Monthly Archives: January 2012

Fixing Packaging Of Web Projects On Your .Net Build Server

On my current project I’m running up the build and deployment environment and hit a roadblock that took me a little while to fathom.  Hopefully reading this might save you some time if you’re having this issue.

The Scenario

1. A build server that does not have Visual Studio installed but has an appropriate .Net SDK that allows you to compile projects successfully.

2. The MSDeploy package on the server – I get mine via the Web Platform Installer (or Web PI for short).

3. A project that you know has valid deployment settings – typically one you can build and package using Visual Studio locally.

4. When building on the server you compile (build) everything OK but the packaging fails silently.

If this sounds like your situation (or similar to it) read on to find a solution.

The Clue

It took me a while to work this out and to be honest the Google Gods were not much use to me (including Scott Guthrie’s blog on all this – see if you can find the follow on blog on automating packaging he hints at).

I tried a range of things before I came across a post on Stack Overflow that pointed me in the right direction.  It refers to the much maligned Microsoft.WebApplication.targets that is installed along with Visual Studio but which is gloriously missing when you build a clean server without Visual Studio.  You’ve probably come across that file before because trying to build without it with Web Application projects ends up with nasty errors being emitted from MSBuild:

error MSB4019: The imported project “C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets” was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

So you know how to fix that – you copy across the necessary files from a machine with Visual Studio and recreate that folder structure on your build server.  Done.

The Fix

The Stack Overflow post specifically mentions that understanding how the MSDeploy stuff works basically boils down to reading the contents of the  Microsoft.WebApplication.targets file.

Hang on, what’s that got to do with packaging?

So I cracked open the targets file and sure enough at one point in it it reads clearly (including good grammar):

<!–This will be overwrite by ..\web\Microsoft.Web.Publishing.targets when $(UseWPP_CopyWebApplication) set to true–>

OK, so now I’m a bit surprised… didn’t MSDeploy lay down some MSBuild support for me? Nope.

At this stage I switched to my working development box and sure enough found a ‘Web’ folder sitting at the same level as the ‘WebApplications’ one.

Web Folder Highlighted in Yellow.

Web Folder Highlighted in Yellow.

I zipped up the contents of this folder and copied to my build server and placed them in the right location (C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Web\).

After this change I re-ran my packaged build and found that the expected build steps and output (a zip and some manifest files) were produced.

So, Hollywood ending to this story then!

Hope it saves you some time.

Tagged , , , , , ,

A Subtle .Net Static Reference Type Gotcha

One of the fundamental concepts that any developer has to understand when developing .Net solutions is the difference between Reference and Value types.  There are a lot of technical discussions online already about the differences between the two but the key concept to pull out of the MSDN description on Reference types is:

“Variables of reference types, referred to as objects, store references to the actual data.”

So, rather than hold the data directly, a Reference type holds a reference to where the data actually is.

/*
Value Type
*/
int someValue = 2;

// someOtherValue holds 2
int someOtherValue = someValue;

/*
Reference Type
*/
MyCustomClass myClassOne = new MyCustomClass();

// myClassTwo holds a reference to myClassOne
MyCustomClass myClassTwo = myClassOne;

Too Much Static

The static keyword will be one that you will come across and use.  A good description of how it affects classes and members can be found on MSDN.  One of the justifications for using static declarations  is around performance – “…a static class remains in memory for the lifetime of the application domain in which your program resides”.

Because of the persistent nature of static variables you will see them used as a poor man’s equivalent to the Application store in ASP.Net.  While quick and easy this approach does have potential to cause issues – especially if you are unaware of the duration of the application domain lifetime and on how you utilise your static variable.  What do I mean by this?

Firstly, think about the application domain for your web application… that’s right, it’s the Application Pool that hosts your web app.

Secondly, think about the users of the web application… that’s right, they may be many different people using the code over many requests – all being served by one long running Application Pool.

So what?  Let us consider the following example.

// ContactList class
public static class ContactList
{
   public static List<FormEmail> Emails { get; private set; }

   public static ContactList()
   {
       Emails = SomeMethodToLoadEmails();
   }
}

Now to use this class in an ASP.Net Application thus.

// Prepare Email List For Sending
public PrepareEmail(FormType type, AdditionalLocation additionalLocation)
{
    FormEmail mailToList = ContactList.Emails.Find(x => x.EmailFormType == type);

    // If this is for NSW we need to add another email
    if(additionalLocation.Location == Location.NSW)
    {
        mailToList.Recipients.Add(additionalLocation.MailOption);
    }
    //...
}

But wait! What happens next time we run this code? Can you spot the problem?

The mailToList variable holds a reference to the ContactList Emails list object which is declared as static. When we call to ‘Add’ at line 9 in the last code sample we will actually add the entry to the original ContactList Emails list.

The result is that until the Application Pool is restarted the ContactList Emails List will continue to be added to which is not what is intended.

A Corrected Way

There are a couple of ways to resolve this issue.  One would be to remove the static nature of the ContactList class and its members, but that may not be the best way to go.

Depending on the object causing the issue you may be able to leverage one of the Copy() or Clone() methods provided by the .Net Framework.  Note that for custom classes you write you will need to provide your own implementation of the Copy() method.

A simple way to resolve the above is to modify the offending code as follows.

// Prepare Email List For Sending
public PrepareEmail(FormType type, AdditionalLocation additionalLocation)
{
    FormEmail mailToList = ContactList.Emails.Find(x => x.EmailFormType == type);

    // Create new local non-static variable and assign values from static matches.
    FormEmail localList = new FormEmail
                              {
                                  Subject = mailToList.Subject,
                                  Template = mailToList.Template
                              };

    // add all recipients from static instance to local one
    localList.Recipients.AddRange(mailToList.Recipients);

    // If this is for NSW we need to add another email
    if(additionalLocation.Location == Location.NSW)
    {
        localList.Recipients.Add(additionalLocation.MailOption);
    }
    //...
}

So there you go, a very subtle issue in using static reference types in your ASP.Net (and WinForms, etc.) projects and how you can go about fixing it.

Hope this saves you some time.

Safely Testing .Net Code That Does Email Delivery

As a .Net developer you will most likely have come across the need to create and send an SMTP (email) message as part of a solution you’ve built.  When under development you will have either stubbed out the mail delivery code or will have substituted a test email address for those of the final recipients in a live environment (did your mailbox get full?!).

This approach is simple and works pretty well under development, but you know one day someone will come to you with a production problem relating to mail delivery to multiple recipients with each receiving their own copy of the message.  How do you test this without needing multiple test mailboxes and without spamming the real recipients?

A few years back I learnt of a way to test mail delivery with real email addresses that can be performed locally of a development machine with minimal risk (note I didn’t say “no risk”) that email will actually be delivered to the intended recipients.  The great thing is you don’t need to understand a lot about networking or being a sysadmin god to get this working.

IIS To The Rescue

Yes, IIS.

In this case you don’t even need any third party software – just the web application server that most ASP.Net developers know (“and love” is probably pushing the relationship a little though I think).

First off, you will need to install the SMTP feature support for IIS on your local machine.  You can get instructions for IIS 7 from TechNet as well as for IIS 6.  If you’re on IIS Express, you’re out of luck – it only supports HTTP and HTTPS.

Once you have the SMTP Feature installed you will need to make one important change – set the SMTP server to use a drop folder.  The IIS SMTP process will simply drop files into a location you’ve selected and there they will sit – each file containing an emaill message.

To make this change open the IIS Manager and select the main server node.  You should see (screenshot below) an option for SMTP E-mail.

IIS Manager with SMTP Email option highlighted

IIS Manager with SMTP Email Option Highlighted.

Double-click the SMTP E-mail option to open the settings dialog. Notice at the bottom the option labelled Store e-mail in pickup directory – you should select this and then select an appropriate location on disk.

SMTP Email Settings Page with Drop Folder Highlighted

SMTP Email Settings Page with Drop Folder Highlighted.

Right, that’s the hard bit done.

Run Teh Codez

Now you have a safe place for your test mail to sit you need to ensure that your code is configured to attempt delivery via the SMTP instance you just configured.  You can most likely achieve this by changing your application’s settings (they’re in an XML config file, right?) so that you use either of “localhost” or “127.0.0.1” as the SMTP host name – you won’t need to change the port from the standard port 25.

Now when you run your code you should find that the mail delivery folder you set will be populated with a range of files consisting of a GUID with a .EML extension – each of these is an individual email awaiting your eager eyes.

Lovely EML Files Ready To View.

Lovely EML Files Ready To View.

The files are plain text so can be opened using Notepad or your favourite equivalent – you can view all the SMTP headers as well as the message body.  For extra goodness you can also open these files in Outlook Express (does anyone even use that any more?!) or Outlook as shown below.

Outlook Goodness - See HTML Email Body Content Easily.

Outlook Goodness – See HTML Email Body Content Easily.

I used this approach just recently to help debug some problems for a customer and I could do it using their real email addresses safe in the knowledge that I would not end up spamming them with junk test emails.

Hope you find this approach useful.

Update

I had a reader pass on a service link to Mailtrap which might be more useful if you’re looking to test with a large diverse team.


Tagged , , , , ,