This is a guest post by Albin Sunnanbo introducing a great hack to work with mails in test environments.
If you have a .NET application that sends emails, this is probably something for you.
TL;DR;
PickupMailViewer is a simple web viewer for emails saved by the specifiedPickupDirectory
SMTP setting in a .NET application.
Download the source, publish to your test server, configure pickup directory and you should be up and running within five minutes.
Outgoing Emails in Test Environments
In your test environment will typically not send real emails, but rather use the specifiedPickupDirectory delivery method for your SMTP-settings in web.config
. This puts all outgoing emails as *.eml files in the file system instead of sending real emails.
IMHO that is the way to go regarding emails in your test environment.
However, there is one drawback, the emails gets dropped in a folder somewhere on your test server. Typically in a location that nobody looks at regularly. In my case I first have to connect a VPN, then open a remote desktop connection to our server, open the folder and copy the desired file back to my own computer (no eml viewer, a.k.a. Outlook, on the test server) and finally open it in Outlook.
Even worse for our testers that don’t even have permissions to login on the test machine. They have to ask a developer to get their emails out of the test system. As you can imagine this only happens when it is absolutely necessary.
A Hack to the Rescue!
One day I got really upset about the big problems here in the world. Poverty, wars and last but not least: VPN:s.
Realizing that the first two was a bit overwhelming to solve for one man with only a few hours to spare i headed for the last and created PickupMailViewer.
PickupMailViewer is a simple web frontend that displays all emails from a file system folder. It’s greatness is its simplicity. One list with all the emails. If you click on an email in the list the full content is opened. That’s about it.
Some Notes About the Development
Reading emails
To read the *.eml files I used “Microsoft CDO for Windows 2000 Library”. It’s a library bundled with IIS that parses EML files. You’ll already have it on your server if you host your web site on IIS.
If want to create your own application that reads EML files, check this library out.
Some Fancy Tricks
Once I got the email parsing working the generation of the email list and previewing and downloading of email contents were pretty straight forward and didn’t take long at all. So once the initial goal was reached I still had a few hours to spare. A few hours to spend on something fun!.
Since reloading a page to see if you have new emails smells of yesterday I wanted to make something more fancy.
I pulled down SignalR, a .NET wrapper around WebSockets (with a few fallbacks for older browsers). SignalR has a nice RPC style API that is pretty easy to get going from the basic hello world chat example. My intention was to push new emails directly to any connected browsers. The missing piece here was how to detect when a new email had arrived. Since emails in this case are just files on disk I used the FileSystemWatcher to receive notifications when new files were created. I then used SignalR to broadcast the email info for the new email as a small JSON document to all connected browsers.
<blink>But with jQuery</blink>
When the email push was done there were no more hours to spend, but at least a few minutes. I used those minutes wisely and managed to sneak in a small jQuery color animation that flashes newly arrived emails in yellow a few times and then slowly fades them back to white. Surprisingly when I show the PickupMailViewer to other people this feature is usually the feature that impresses the most.
SignalR
Being the first project where I actually used SignalR I made some surprising discoveries. It is not tightly integrated with ASP.NET MVC.
My first attempt of rendering the email items I pushed via SignalR was to reuse the MVC views I used when rendering the initial page. The MVC engine is quite tightly coupled to an incoming http request, but we don’t have any http request when our trigger for pushing data is a file system event. There are some ways around this, but they all have their limitations. Attempt abandoned.
My first working attempt was to create a string concatenating hack in JavaScript that created the same markup as my MVC views. Pretty ugly, but it served the purpose of getting things up and running very quickly. However it wasn’t nice to maintain and I had a few inconsistency bugs.
The only way to go seems to be client side rendering. I thought about well known frameworks like AngularJS, Knockout and the recently announced Aurelia. Having used none of them before it seemed to be more complicated to bring one of them in than keep the existing four lines of string concatenation. After a bit of research I settled on a light weight compromise. {{mustache.js}}, a one way template engine. It requires just a few minutes skimming though the documentation to master the templating process.
Once I got mustache working for the push updates I replaced my ASP.NET MVC views with a single JSON representation of the list content. In document.ready I rendered all list content on the client side with the same mustache template I used for the push updates. Finally I got rid of the duplicated rendering paths and the code looked much more clean.
Source
If you want to try your self I have published the source code on GitHub. It’s only about 500 lines of code, including empty lines and brackets, excluding imported libraries. Certainly not much code for a web application with real time push updates.
Features
Almost none.
Some sorting and/or filtering would be nice. Download links for attachments would be nice too. Pull requests are welcome!