Ryan Hoffman

Thoughts from a .NET obsessed software architect and developer.

Configure Cassette to Bundle Twitter Bootstrap Javascript

I originally thought bundling the Bootstrap javascript would be as easy as adding the folder to a Cassette bundle. There was one problem - there is a dependency between bootstrap-popover.js and bootstrap-tooltip.js - and I do not want to modify the original Bootstrap files.

I’ve used a creative approach to add the dependency - using the cool customize bundles lamba in the Cassette bundle configuration. I use a Linq query to locate the assets in question, and I manually add a reference in code. It’s really cool that Cassette allows you to get “low” level like this!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class CassetteBundleConfiguration : IConfiguration<BundleCollection>
{
    public void Configure(BundleCollection bundles)
    {
        bundles.Add<ScriptBundle>
        (
            "Content/bootstrap/js", //relative path to your bootstrap js files
            new FileSearch()
            {
                SearchOption = SearchOption.TopDirectoryOnly,
                Pattern = "*.js"
            },
            bundle =>
            {
                var tooltipJs = bundle.Assets.Single(a => a.Path
                                                           .ToLowerInvariant()
                                                           .Contains("-tooltip"));

                var popoverJs = bundle.Assets.Single(a => a.Path
                                                           .ToLowerInvariant()
                                                           .Contains("-popover"));

                popoverJs.AddReference(tooltipJs.Path, 1);
            }
        );
    }
}

Looking for how to configure Cassette to bundle the Bootstrap LESS stylesheets? There are instructions here and although they are for Cassette 1.0, it still works the same.

Remap Home and End on OS X 10.8 Mountain Lion

One of the things I miss the most from my PC keyboard is how the Home and End keys work. In a text editor on Windows, Home will move the carrot to the beginning of the current line, and End will move the carrot to the end of the current line. On Mac OS X, Home moves the carrot to before the first character in the whole document, and the End moves the carrot to after the last character in the document. I often use Shift+Home/End in software development to select a whole line, and I miss this a lot. After some tinkering, the best way to do this is to use software called KeyRemap4Macbook, available here.

After KeyRemap4Macbook is installed, you configure it in the System Preferences app. On the “Change Key” tab, search for “Use PC Style Home/End” and toggle the option on that says “Use PC Style Home/End (except in Virtual Machine, RDC) (Change Home to Control+A) (Change End to Control+E)”. It is as easy as that!

Despite the awful UI that KeyRemap4MacBook has, it works very well. I wish you were able to configure all of the customizations in the UI, and I also wish there was much better organization of the pre-defined key remaps.

Add to the PATH on Mac OS X 10.8 Mountain Lion

I just bought a neat Mac Mini!  I’m using it to do some MonoTouch and Mono for Android development!  In the process of setting everything up, I installed node.js.  After the node.js installer finished, it recommended to add /usr/local/share/npm/bin to my path.  It turns out there is a very neat way to do this in OS X, the /etc/paths file!  The file contains a list (one per line) of paths that are added to the $PATH variable in the shell.    Here are some quick directions to add to the path:

  • Open up Terminal.
  • Run the following command:
1
sudo nano /etc/paths
  • Enter your password, when prompted.
  • Go to the bottom of the file, and enter the path you wish to add.
  • Hit control-x to quit.
  • Enter “Y” to save the modified buffer.

That’s it!  To test it, in new terminal window, type:

1
echo $PATH

You should see something similar to this (including the path you’ve added!):

1
2
MacMini:~ ryan$ echo $PATH
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/share/npm/bin

Here is a screenshot of what my file looks like:

From SQL Server to MongoDB

Tonight at the MongoDB NYC Meetup, I gave a presentation on how TNTP moved from SQL Server to MongoDB. I would like to thank the awesome folks at 10gen for giving me the opportunity to talk about my experiences with their great product. If you are interested in attending a future meeting of the meetup, join it on Meetup.com, here. Without further ado, here are the slides and a recording of the presentation!

Video:

Slides:

nClam: A .NET Library to Virus Scan

Here is a very common scenario: You have an ASP.NET website (WebForms or MVC). It has a feature that accepts a file upload from your users. Other visitors of your site are then able to download that file to their computer.

You might ask, is there a problem with this scenario? Well, I would say, probably. If a user uploads an infected file to your website, you will be essentially distributing that infected file to any of your other potential visitors. That’s not good. So what can you do? Scan that upload with a virus scanner!

I’ve done a lot of research and unfortunately found that there are very few libraries for .NET which allow on-demand scanning. There are a couple that have a $1k+/year price tag and while they might have good features, it seems extremely pricy for virus scanning some file uploads. There is however, a really great open source antivirus engine called ClamAV. It looks like in the past there have been some efforts of making a ClamAV client for .NET, however the projects I found seem years old and I could not find anything that worked out of the box. So I went to work.

I had a prototype of nClam, a pure .NET client to ClamAV, ready in a few hours. From there I polished up the code, added documentation, pushed it up to GitHub, and published a package to Nuget.

Using nClam is very easy. It has one pre-requisite, a ClamAV server. In the past, ClamAV was difficult to get running on Windows, but the team has done a lot of work on the Windows version and it’s able to install as a Windows Service right out of the box now. Here are some quick steps to installing ClamAV:

  • Download the 32-bit or x64 version of ClamAV here: http://oss.netfarm.it/clamav/.
  • Extract the ClamAV binaries to C:\clamav
  • Create an empty folder called DB in C:\clamav
  • From a command prompt in C:\clamav, run freshclam.exe (this will download the latest virus definitions)
  • Install the ClamAV service by running: clamd –install
  • Install the ClamAV Virus Updater service by running:
  • Open up the Windows Services list and set the “ClamWin Free Antivirus Scanner Service” and the “ClamWin Free Antivirus Database Updater” to Startup Type: Automatic and start them.
  • The ClamAV Server is now set up!

Once ClamAV is running, you can now on-demand scan anything from code using nClam. Using nClam is easy! First, get the nuget package nClam (or download it from github) and reference it in your project. From there, instantiate a ClamClient object with the location of your server (which is probably localhost at this point) and the port it is running under (default is 3310) and call one of the Scan methods! These methods return a ClamScanResult object, which has a handy enum which tells you if your scan was clean or a virus was detected. Here is some sample code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var clam = new ClamClient("localhost", 3310);
var scanResult = clam.ScanFileOnServer("C:\\test.txt");  //any file you would like!

switch (scanResult.Result)
{
    case ClamScanResults.Clean:
        Console.WriteLine("The file is clean!");
        break;
    case ClamScanResults.VirusDetected:
        Console.WriteLine("Virus Found!");
        Console.WriteLine("Virus name: {0}", scanResult.InfectedFiles.First().VirusName);
        break;
    case ClamScanResults.Error:
        Console.WriteLine("Woah an error occured! Error: {0}", scanResult.RawResult);
        break;
}

nClam is free and open source. It is published under the very open Apache 2 license. Here are some links to get nClam:

As always, I would love some feedback on this. Feel free to post this to your blogs, tweet about it, and share it to any .NET developer. Let’s make our applications more secure!

.NET 4 Hidden Gem: System.Lazy

I’ve been using .NET 4.0 at work since Beta 1. Yes, it’s been about a year+ now. Now that .NET 4 / VS2010 has RTM’ed, lots of developers are grabbing the new bits. Because of this, I’m going to make a series of posts about some new hidden gemss (aka features I really like :-D) in .NET 4.

One really cool new class in the BCL is System.Lazy. The beauty of this object is it allows you to define complex or potentially long running initialization code for an object and ensure it only executes once, which it handles automatically. The lazy object allows you to write initialization code for an object, which is passed to it in as a Func<T>. Here’s a simple example of how to create a new Lazy object:

1
var lazy = new Lazy<string>(() => LongRunningMethodGetsString());

Lazy provides two properties, IsValueCreated and Value. You use IsValueCreated (which returns a bool) to determine if the object has been initialized. The Value property returns a type T, which returns the object that you create in your initializer code. When you first create a new Lazy object, IsValueCreated is false, until you call the Value property. Your initializer code only runs once, and the Lazy object will always return the result when you call Value.

I have a nice little pattern around the lazy object, which wraps a read-only property around a private lazy object. This makes it easier for consumers of your class to use a lazy object that you are using, by just returning T instead of Lazy<T>.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Awesomeness
{
    private Lazy<AwesomeObject> _ourAwesomeObject = new Lazy<AwesomeObject>(() =>
    {
        var awesomeObject = new AwesomeObject();
        //do stuff here to build your awesomeObject
        return awesomeObject;
    });

    public AwesomeObject OurAwesomeObject
    {
        get { return _ourAwesomeObject.Value; }
    }
}

One last word of advice when using Lazy: always make sure that your initializer does not throwan exception. If it throws an exception (or an unhandled exception occurs), then any calls to the Value property will aways re-throw this exception. In the case that your initializer could throw an exception, either wrap it in a try block, or just don’t use the Lazy object all together (perhaps by keeping a private field with the initialized value and checking to see if it is null).

Using Windows AppFabric Caching (Velocity) Beta 2 With .NET 4.0 RTM

One of the awesome Microsoft tools that I’m fortunate to work with is Windows AppFabric Caching, codenamed Velocity. It’s a distributed caching engine, not unlike MemCache. I think overall it works really great in my application’s usage, and I also love how there is a Session plugin which is great for running under a farm. My project has been using .NET 4.0 since Beta 1, so you could call us early adopters. Last week when Visual Studio 2010 and .NET 4.0 RTMed, my entire team immediately upgraded. Our entire code base worked as-is with no code changes (we upgraded from the .NET 4 RC). The one thing I was surprised about was that the AppFabric Caching service did not start - in fact, it immediately failed. I quickly posted on the MSDN Forums about this, here: http://social.msdn.microsoft.com/Forums/en-US/velocity/thread/681a2283-a735-488a-aeeb-cdbcfd06d58c.

I received a not so awesome reply:

Beta2 works only with RC release of .Net 4/VSTS 2010. You’ll need to wait for the upcoming RC release which will work with .Net4 RTM.

With that said, I went off to figure out if I could make this work, despite Microsoft’s guidance, especially considering our code base upgraded with 0 changes. It turns out there is a simple fix for the issue. All you need to do is edit %windir%\System32\AppFabric\DistributedCacheService.exe.config and make these changes: Replace

1
<supportedruntime version="v4.0.30128"></supportedruntime>

With:

1
<supportedruntime version="v4.0.30319"></supportedruntime>

With this one simple change, everything works great! There is one other issue. What if you need to install AppFabric Caching, with .NET 4.0 RTM installed? Well, the answer is, you can’t. You have to uninstall the .NET 4.0 RTM, install the .NET 4.0 RC, install AppFabric Caching, then uninstall the RC, and install the RTM. Yes, this is a huge pain, but since the AppFabric installer is not an MSI, and has a dependency on the .NET 4.0 RC, I can see no other way to get around this. At least it is *possible* to do this.

Console.WriteLine(“Hello, World!”)

First post!  Hello everyone who is visiting this blog.  I’m Ryan Hoffman, and I’m a software architect focused on .NET solutions.  I’ve recently gotten into photography, and I’m posting lots of pictures to flickr.  I’m going to use this blog to share useful tips/ideas in development, and also just any other thoughts that I have!