ASP .NET 5 Application Configuration, Part 2

In Part 1, we saw how to retrieve basic application settings from a range of formats available in ASP .NET 5. In this article, we will see techniques used for settings that go beyond simple key-value representation.

Getting a Config Section

Let’s say we have this appsettings.json:

{
  "Title": "configuration",
  "DataSettings": {
    "ConnectionString": "SomeConnectionString",
    "AuditDatabaseName": "AuditDB"
  }
}

…and we want to map the DataSettings to the following C# class:

    public class DataSettings
    {
        public string ConnectionString { get; set; }
        public string AuditDatabaseName { get; set; }
    }

We can start with configuration loading code from the Part 1 article:

        public void ConfigureServices(IServiceCollection services)
        {
            var configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddJsonFile("appsettings.json");
            Configuration = configurationBuilder.Build();

            // TODO code goes here
        }

At this point, we need to add the following dependency to our project.json:

    "Microsoft.Extensions.OptionsModel": "1.0.0-rc1-final"

Then, in the TODO part in the code above, we can add the following to read the DataSettings section into its strongly-typed C# class equivalent:

        public void ConfigureServices(IServiceCollection services)
        {
            var configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddJsonFile("appsettings.json");
            Configuration = configurationBuilder.Build();

            var section = Configuration.GetSection("DataSettings");
            services.Configure<DataSettings>(section);
        }

You may be disappointed to find that this doesn’t give you an object you can use right away. However, what we are doing is putting our config section in the services collection, which is basically ASP .NET 5’s built-in dependency injection. In the next section, we’ll see how we can actually use this.

Note that by reading a config section, you’re basically pulling out only that section from the config. In the example above, the Title setting is not included in the section we read.

Dependency Injection with the Options Model

One of the most important parts of ASP .NET 5 Configuration is the options model, which is just a fancy way of saying dependency injection. By calling services.Configure() in the previous section, we have set up our settings class with dependency injection. So how do we use it?

Let’s make a simple Web API controller to see this in action. In ASP .NET 5, Web API and MVC are the same thing, so we’ll need the MVC package. Also make sure you have the OptionsModel package from the previous section:

    "Microsoft.Extensions.OptionsModel": "1.0.0-rc1-final",
    "Microsoft.AspNet.Mvc": "6.0.0-rc1-final"

We’ll need to do some simple setup in Startup.cs for MVC to work:

        public void ConfigureServices(IServiceCollection services)
        {
            var configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddJsonFile("appsettings.json");
            Configuration = configurationBuilder.Build();

            var section = Configuration.GetSection("DataSettings");
            services.Configure<DataSettings>(section);

            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();

            app.UseMvc();
        }

Finally, we can add our controller:

    [Route("api/[controller]")]
    public class DataController : Controller
    {
        IOptions<DataSettings> dataSettings;

        public DataController(IOptions<DataSettings> dataSettings)
        {
            this.dataSettings = dataSettings;
        }

        public IActionResult Index()
        {
            return new ObjectResult(this.dataSettings.Value.ConnectionString);
        }
    }

Notice how by putting an IOptions<DataSettings> in the constructor, we can get our settings class from the dependency injection framework. Accessing its Value gives us the DataSettings instance that we configured earlier.

Sure enough, it works:

aspnet5-web-api-dependency-injection

Strongly-Typed Configuration from Root

We don’t always need to read just a section. Sometimes, it can be handy to read the whole configuration file.

So let’s say I have these settings classes:

    public class MySettings
    {
        public string Title { get; set; }
        public List<string> SupportedFormats { get; set; }
        public List<Hero> Heroes { get; set; }
    }

    public class Hero
    {
        public string CharacterName { get; set; }
        public string ActorName { get; set; }
    }

Our appsettings.json now contains the following:

{
  "Title": "configuration",
  "SupportedFormats": [ "json", "xml", "ini" ],
  "Heroes": [
    {
      "CharacterName": "Luke Skywalker",
      "ActorName": "Mark Hamill"
    },
    {
      "CharacterName": "Han Solo",
      "ActorName": "Harrison Ford"
    }
  ]
}

Then, I can read all this stuff into MySettings as follows:

        public void ConfigureServices(IServiceCollection services)
        {
            var configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddJsonFile("appsettings.json");
            Configuration = configurationBuilder.Build();

            var mySettings = new MySettings();
            Configuration.Bind(mySettings);
        }

And… there you go:

aspnet5-config-from-root

If you take a moment to look at the stuff I put into the appsettings.json, you’ll begin to appreciate just how powerful this is. We can read basic strings, arrays, and even lists of entire objects like this. If you’ve experienced what a pain in the ass it is to read a simple list of data from a key in Web.config with the ASP .NET we’re used to, then this should feel like a breath of fresh air.

Custom Configuration Providers

If none of the default setting file formats match what you need, then you’ll probably need to create your own custom configuration provider. The example in the official docs shows a reasonable example: retrieving settings from a database. Unfortunately, however, that example doesn’t work (at the time of writing this article), because the APIs have changed and the official docs have not been updated.

Just for the sake of example, let’s imagine we want to load a file containing pipe-delimited settings. We’ll work with the following pipeconfig.txt:

key1|value1|key2|value2

Our custom provider class needs to:

  1. Inherit from ConfigurationProvider
  2. Override the Load() method
  3. Set the Data dictionary

Here’s an example of what our pipe-delimited-setting loader could look like:

    public class PipeDelimitedConfigSource : ConfigurationProvider
    {
        private string filename;

        public PipeDelimitedConfigSource(string filename)
        {
            this.filename = filename;
        }

        public override void Load()
        {
            string fileContents = File.ReadAllText(filename);
            string[] tokens = fileContents.Split(new char[] { '|' });

            for (int i = 0; i < tokens.Length; i += 2)
            {
                var key = tokens[i];
                var value = tokens[i + 1];
                this.Data[key] = value;
            }
        }
    }

Then, back in Startup.cs, we can feed it to our ConfigurationBuilder using its Add() method:

        public void ConfigureServices(IServiceCollection services)
        {
            var configurationBuilder = new ConfigurationBuilder();
            var configSource = new PipeDelimitedConfigSource("../pipeconfig.txt");
            configurationBuilder.Add(configSource);
            Configuration = configurationBuilder.Build();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();

            app.Run(async (context) =>
            {
                var setting1 = this.Configuration["key1"];
                var setting2 = this.Configuration["key2"];
                string output = $"<h1>{setting1}</h1><h2>{setting2}</h2>";

                await context.Response.WriteAsync(output);
            });
        }

Here’s the output:

aspnet5-custom-config-examplet

Config files and wwwroot

Before ASP .NET 5, configuration resided in Web.config. Having a single file makes it easy to configure web servers not to serve it. The flexibility afforded by having different possible formats and source for configuration in ASP .NET 5 thus begs the question: how do we prevent our config files from being served?

This is easy to deal with if we understand the role of the wwwroot folder. Before ASP .NET 5, the project root and the website root were one and the same. In ASP .NET 5, the website root (called wwwroot by default, but configurable) is a subfolder of the project folder. Thus, to keep files out of reach, it is necessary only to keep them out of wwwroot.

This way, the application code will have access to these files, but they will not be served as static files via simple web requests.

The role of web.config

By reading this article and the previous one, you have hopefully learned that there is no longer a standard web.config file that stores all the web application’s settings. With this in mind, you might be a little surprised to find that standard ASP .NET 5 project templates actually come with a web.config in the wwwroot folder.

At the time of writing this article, the contents of the file (although not important here) are the following:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
    </handlers>
    <httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600"/>
  </system.webServer>
</configuration>

The reason for the presence of the web.config is explained in this StackOverflow answer, which I quote:

“Web.config is strictly for IIS Configuration. It is not needed unless hosting in IIS. It is not used when you run the app from the command line.

“In the past Web.config was used for both IIS configuration and application configuration and settings. But in asp.net 5 it is not used by the application at all, it is only used for IIS configuration.

“This decoupling of the application from IIS is part of what makes cross platform possible.”

Summary

In this article, we have seen more complex ways in which we can read application configuration. The configuration model in ASP .NET 5 is indeed powerful, as we can map settings files to strongly-typed objects, and pass them on to our controllers via dependency injection. Where necessary, we can extend the range of built-in configuration providers by creating our own.

In the final sections, we have also discussed how to protect settings files from being accidentally served over the web, and why there is a web.config file in wwwroot by default despite ASP .NET 5 doing away with web.config.

ASP .NET 5 Application Configuration, Part 1

ASP .NET 5 moves away from the traditional web.config for storing application configuration. Instead, the configuration itself is configurable, and developers may use a combination of different sources. Support for JSON, XML, INI, environment variables, command-line arguments and in-memory configuration are all available. It is also possible to specify custom configuration sources.

Using JSON Configuration

ASP .NET 5 supports a number of different formats for application settings. The preferred format is JSON. In Visual Studio, you can add a new ASP.NET Configuration File, which by default is called appsettings.json:

aspnet5-add-appsettings.json

Let’s keep things simple for now, so throw out the default contents of appsettings.json and replace them with the following instead:

{
  "title": "My Brand New Website",
  "subtitle": "The one and only"
}

In Startup.cs, we need to set up our configuration. We do this thanks to ConfigurationBuilder as follows:

        private IConfiguration Configuration { get; set; }

        public void ConfigureServices(IServiceCollection services)
        {
            var configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddJsonFile("appsettings.json");
            Configuration = configurationBuilder.Build();
        }

We’ll see more about the capabilities of ConfigurationBuilder shortly, but for now, all we need is JSON support. In this simple example, since we’re going to use configuration directly within the Startup class, we’re putting our configuration in a Configuration property within the same class. Normally, however, we would set up our configuration in the application’s dependency injection so that it can be used elsewhere. We’ll see how to do that later, too.

Now, we just have to actually use that configuration:

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();

            app.Run(async (context) =>
            {
                var title = this.Configuration["title"];
                var subtitle = this.Configuration["subtitle"];
                string output = $"<h1>{title}</h1><h2>{subtitle}</h2>";

                await context.Response.WriteAsync(output);
            });
        }

Don’t understand the funny $ syntax? That’s string interpolation, a new feature in C# 6.

Here’s the output:

aspnet5-example-json-config

Using XML Configuration

XML configuration isn’t going away anytime soon. And although it’s supported by official packages, it’s not so out-of-the-box as many sources claim. To enable XML configuration support, you need to add a NuGet package to your project.json dependencies:

  "dependencies": {
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
    "Microsoft.Extensions.Configuration.Xml": "1.0.0-rc1-final"
  },

Once that is done, a new extension method is available for ConfigurationBuilder that you can use:

        public void ConfigureServices(IServiceCollection services)
        {
            var configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddXmlFile("appsettings.xml");
            Configuration = configurationBuilder.Build();
        }

As an example, I’m going to use the following XML file, named appsettings.xml:

<root>
  <title>My XML-driven website</title>
  <subtitle>On a server far, far away</subtitle>
</root>

Without changing the code we added to Configure() in the previous section, here’s the result:

aspnet5-example-xml-config

Using INI Configuration

ASP .NET 5 also supports a simple, medieval configuration format called INI files. Like with XML, these don’t come right out of the box, and you need to add the necessary NuGet package to your project.json‘s dependencies to support them:

  "dependencies": {
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
    "Microsoft.Extensions.Configuration.Xml": "1.0.0-rc1-final",
    "Microsoft.Extensions.Configuration.Ini": "1.0.0-rc1-final"
  },

To see this in action, we need an example INI file, which we will call appsettings.ini, and which will contain the following:

title=Another format!
subtitle=They never end

And as with XML, we need to slightly change our configuration code:

        public void ConfigureServices(IServiceCollection services)
        {
            var configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddIniFile("appsettings.ini");
            Configuration = configurationBuilder.Build();
        }

Once again, this works wonderfully:

aspnet5-example-ini-config

Environment Variables

Environment variables can also be used as a source for application settings. We can set things up to actually get our application settings from the environment variables:

        public void ConfigureServices(IServiceCollection services)
        {
            var configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddEnvironmentVariables();
            Configuration = configurationBuilder.Build();
        }

For demonstration purposes, we’ll use an existing environment variable. Adding new ones probably requires a restart. Let’s modify our serving code a little:

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();

            app.Run(async (context) =>
            {
                var dnxHome = this.Configuration["DNX_HOME"];
                string output = $"<p>{dnxHome}</p>";

                await context.Response.WriteAsync(output);
            });
        }

Here’s the output:

aspnet5-example-env-config-1

If you don’t want all your environment variables to be accessible to the application, you can specify a prefix that environment variables need to start with. For instance, if I specify “DNX_” as the prefix, then I should get access to “DNX_HOME”, but not to “TMP”. In this case, we specify the prefix in AddEnvironmentVariables(), but omit it when accessing the application setting:

        public void ConfigureServices(IServiceCollection services)
        {
            var configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddEnvironmentVariables("DNX_");
            Configuration = configurationBuilder.Build();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();

            app.Run(async (context) =>
            {
                var dnxHome = this.Configuration["HOME"];
                string output = $"<p>{dnxHome}</p>";

                await context.Response.WriteAsync(output);
            });
        }

The output is still the same as before:

aspnet5-example-env-config-2

But this time, the application doesn’t have access to all the environment variables in the system:

aspnet5-example-env-config-4

The contents of the above screenshot are a bit of a surprise, actually. On my system, “DNX_HOME” is the only environment variable starting with “DNX_”. I assume all the rest are created as part of the DNX runtime environment when the application is run.

In-Memory Configuration

At the time of writing this article, the official docs about ASP .NET 5 Configuration show a MemoryConfigurationSource class which can be used to get and set application settings on the fly in code. The page says it requires Microsoft.Framework.ConfigurationModel.

My guess is that the documentation is out of date, because the latest packages are all like Microsoft.Extensions.* and the latest version of Microsoft.Framework.ConfigurationModel is beta 4. I haven’t been able to locate the replacement package for this.

Update 10th January 2016: The ASP .NET documentation has been updated just a few days ago for RC1 (about time), and it turns out that what used to be MemoryConfigurationSource is now called MemoryConfigurationProvider. The rest of this section has been added in light of this.

It is possible to create configuration settings entirely in memory. For this, we create a MemoryConfigurationProvider, and either pass initial configuration data in the constructor or call its Set() method to add a key/value pair. Here’s a simple example:

        public void ConfigureServices(IServiceCollection services)
        {
            var configurationBuilder = new ConfigurationBuilder();

            var memConfig = new MemoryConfigurationProvider();
            memConfig.Set("name", "Joe");

            configurationBuilder.Add(memConfig);
            Configuration = configurationBuilder.Build();
        }

We can test this as follows:

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync($"Hello {Configuration["name"]}!");
            });
        }

Here’s the result:

aspnet5-config-memory

Command-Line Arguments

ConfigurationBuilder provides a method which can be used to build configuration based on command-line arguments:

            configurationBuilder.AddCommandLine(args);

This is demonstrated in the ASP .NET 5 Configuration official documentation using a console application.

It is not clear how this would work for a web application. Whenever I try to run the web application, whether from VS2015 or using the command line tools, Main() does not get invoked, and control goes directly to ConfigureServices(), which knows nothing about the command line arguments.

Hierarchical Retrieval

One of the advantages of the new ASP .NET 5 Configuration model is that you can organize your application settings into hierarchies. If we go back to the JSON example and add back the default appsettings.json file generated by Visual Studio, we get this:

{
    "Data": {
        "DefaultConnection": {
            "ConnectionString": "Server=(localdb)\\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;"
        }
    }
}

We can retrieve inner settings using a colon syntax such as this:

                var connStr = this.Configuration["Data:DefaultConnection:ConnectionString"];

Let’s change our Configure() code to use the new setting:

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();

            app.Run(async (context) =>
            {
                var connStr = this.Configuration["Data:DefaultConnection:ConnectionString"];
                string output = $"<pre>{connStr}</pre>";

                await context.Response.WriteAsync(output);
            });
        }

And here’s the result:aspnet5-example-hierarchical-config

Combining Configurations

So far we have seen one configuration source at a time to keep things simple. But as a matter of fact, you can specify multiple sources for your application settings. The order is important, because sources specified later will override settings also found in sources specified earlier. For example, let’s say we have:

        public void ConfigureServices(IServiceCollection services)
        {
            var configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddIniFile("appsettings.ini")
                                .AddEnvironmentVariables("DNX_");
            Configuration = configurationBuilder.Build();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();

            app.Run(async (context) =>
            {
                var home = this.Configuration["HOME"];
                var work = this.Configuration["WORK"];
                string output = $"<p>Home: {home}</p><p>Work: {work}</p>";

                await context.Response.WriteAsync(output);
            });
        }

Our environment variables contain a “DNX_HOME”. As before, since we’re using a “DNX_” prefix, getting the “HOME” setting actually retrieves “DNX_HOME”. Now, let’s say our appsettings.ini file contains the following:

HOME=Where the heart is
WORK=Where the fun is

Here’s what we get:

aspnet5-configuration-combined-example

What happened here? The “HOME” setting taken from our environment variables has overwritten that in the INI file. However, the “WORK” setting was taken from the INI file because there is none specified in the environment variables.

Summary

In this article, we have seen how we can work with simple application settings in ASP .NET 5. JSON, XML, INI and environment variables are all viable configuration sources to use. In-memory configuration and command-line parameters are a bit more obscure at the time of writing this article.

Additionally, thanks to a more complex configuration model, we can retrieve settings from a hierarchy, and we can combine settings from various sources. Remember: the later ones take precedence!

In Part 2, we will go beyond simple setting retrieval, and learn more complex ways to work with settings in a real-world application.

Inconsistent Toggles in Windows 10 Taskbar Menu

There’s something I found really odd about the Windows 10 taskbar. There are two special buttons next to the Start button: the Search button, and the Task View button. You can toggle the visibility of each from the context menu that comes up when you right click on the taskbar.

We can toggle the Task View button by simply clicking on the “Show Task View button” item in the menu. When the Task View button is visible, this item is checked:

win10-show-task-view-on

…and when it’s not visible, the item is not checked:

win10-show-task-view-off

Simple, no? Let’s do the same for the Search button. Right now it’s on…

win10-show-search-on

So when I click “Show search icon”, following the same logic as with the Task View button, I would expect it to disappear, right?

Nope. Clicking that won’t do anything, because you instead have to select “Hidden”. Then, when Search is not visible, it looks like this instead:

win10-show-search-off

Okay, it’s easy to get used to this after tripping on it the first time. But why would anyone ever provide these kinds of confusing and inconsistent options?

Aside from this, that Search submenu is clearly overkill, given that they could have implemented a single toggle menu item as with Task View. This is exactly like using two checkboxes for the opposites of same thing and expecting them to be mutually exclusive. By way of analogy, can you imagine how stupid this would look?

win10-gender-analogy

This would tell you that the Male and Female options are unrelated; you could potentially pick both.

Update 24th December 2015: As pointed out in these comments on Reddit, apparently the reason for having a separate menu for the Search icon is that in regions where Cortana is enabled, there are actually three options. They could have at least used bullets instead of checkmarks though, which would have made them feel like radio buttons (making the mutual exclusion obvious) rather than checkboxes.

ASP .NET 5 Preview: Serving Static Files

One of the most basic features of just about any non-trivial web application is that of serving static files.  Typically, a browser will request all kinds of files: HTML documents, JavaScript files, images, etc.

In ASP .NET 5, the root of the website is (by default) a folder called wwwroot. Any files to be served by the web application should be placed within this folder. However, the ability to serve static files doesn’t come out of the box. To support static files, you need to add the Microsoft.AspNet.StaticFiles NuGet package to your project.json:

  "dependencies": {
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
    "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
  },

Then, in your Configure() method (Startup.cs), call UseStaticFiles():

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();
            
            app.UseStaticFiles();

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }

Rebuild and run your application:

dnu restore
dnu build
dnx web

…and you can now retrieve files:

aspnet5-staticfiles-text

If you go to the root of the URL, though, you’ll notice that your index.html doesn’t get retrieved unless you request it explicitly:

aspnet5-staticfiles-nodefault

That “Hello World” is coming from the end of the pipeline we defined in Configure(), because UseStaticFiles() doesn’t know what to return if we don’t specify a file that exists. We can sort this out by calling UseDefaultFiles():

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();
            
            app.UseDefaultFiles();
            app.UseStaticFiles();

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }

UseDefaultFiles() will look for typical default files such as index.html, default.html, etc. It must be declared before UseStaticFiles(), or it won’t work. We now get our default page:

aspnet5-staticfiles-withdefault

If you want to show a directory listing for folders with no such default files, call UseDefaultFiles() (note: again, order is important):

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();
            
            app.UseDefaultFiles();
            app.UseDirectoryBrowser();
            app.UseStaticFiles();

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }

Our root still serves the default index.html, but when navigating to the images folder, we are presented with a directory listing:

aspnet5-staticfiles-dirlisting

You can also achieve what we have done so far using the UseFileServer() method. Refer to the official documentation on static files to learn how to use UseFileServer(), and for additional configuration options provided by the features we have seen so far.

ASP .NET 5 Preview: Hello World with Yeoman

ASP.NET 5 (formerly known as ASP .NET vNext) is the next generation of ASP .NET, still in a prerelease state. At the time of writing, the current runtime version is 1.0.0-rc1-update1, and ASP .NET 5 is set to launch in Q1 2016. The APIs seen here may change in the time leading up to that release; in fact, this article is written precisely to address recent API changes.

ASP .NET 5 is a game changer, and everything we’ve learned in ASP .NET so far no longer applies. In this article, we’ll see how to do a basic “Hello World” with ASP .NET 5. This usually sounds like something easy, but given that things are changing pretty quickly (even fundamental things such as the IIS hosting model), it’s not. In fact, I would have liked to say you can create a new project in Visual Studio and select the “Empty” ASP .NET 5 Preview Template:

aspnet5-empty-preview-template

Unfortunately, however, these templates are so outdated that they no longer work. Starting with these and getting them to work is an exercise in frustration. Fortunately, however, there’s an alternative way to easily set up an ASP .NET 5 project. And, surprise surprise, it does not involve Visual Studio.

Update 27th December 2015: If you do want to use the latest Visual Studio templates, install Visual Studio 2015 Update 1 as well as the latest ASP .NET 5 Release Candidate.

Yeoman provides a tool called yo, which allows you to create a new web application from various different templates. Nowadays, with so many tools and technologies, it is sometimes difficult to piece things together. You can use yo and its generators to set up a web application with the bits and pieces you need without much effort. For example:

  • Want to create an AngularJS Single-Page App (SPA)? No problem, there’s a generator for that.
  • Want to create an ASP .NET MVC application? No problem, there’s a generator for that.
  • Want to create an ASP .NET 5 empty application? No problem, there’s a generator for that too.
  • Want a full rack of barbecue ribs with fries? I don’t think there’s a generator for that, but perhaps someone may write one someday.

Like various other web tools, yo and its generators require npm, the node.js package manager. You will first need to install node.js, and npm comes packaged with it. You can then install yo by running the following command from the command prompt:

npm install -g yo

In order to generate a web application template, yo relies on plugins, called generators. At the time of writing, there are several generators for ASP .NET 5, but generator-aspnet is the only one that’s up to date. Let’s also install it using the following command:

npm install -g generator-aspnet

With that done, we can now generate our ASP .NET project. You can either invoke yo and do it interactively:

yeoman-interactive-2

…or just invoke the following command:

yo aspnet

You will then be asked a few questions that allow you to configure your ASP .NET 5 project. For starters, we’ll create an Empty Application:

aspnet5-yeoman-application-type

You will then be asked for the name of your application, after which the web app skeleton will be generated, and you will be told the commands you need to build and run it:

aspnet5-yeoman-application-generated

Before we run these commands, let’s take a second to see what our project actually contains. The files we care about are Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.Extensions.DependencyInjection;

namespace myapp
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }

        // Entry point for the application.
        public static void Main(string[] args) => Microsoft.AspNet.Hosting.WebApplication.Run<Startup>(args);
    }
}

…and project.json:

{
  "version": "1.0.0-*",
  "compilationOptions": {
    "emitEntryPoint": true
  },
  "tooling": {
    "defaultNamespace": "myapp"
  },

  "dependencies": {
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final"
  },

  "commands": {
    "web": "Microsoft.AspNet.Server.Kestrel"
  },

  "frameworks": {
    "dnx451": { },
    "dnxcore50": { }
  },

  "exclude": [
    "wwwroot",
    "node_modules"
  ],
  "publishExclude": [
    "**.user",
    "**.vspscc"
  ]
}

Now, in order to proceed, you need to have the DNX tools (dnu, dnvm and dnx). If you don’t have them, you can get them when you install Visual Studio 2015, or by following the instructions on the ASP .NET 5 Github page. You may also need to upgrade to the latest runtimes (use dnvm list to check what you’re using, dnvm upgrade to get the latest, and dnvm use <runtime> to switch to the latest) – learning to use the DNX tools is beyond the scope of this article.

Once you have DNX in place, you can run the commands suggested by the aspnet generator earlier. First, cd into the application directory:

cd myapp

Then, run the following command to restore packages (essentially works like NuGet):

dnu restore

You can now build the web application using the following command:

dnu build

Finally, the following command runs the application. You’ll notice that web is actually one of the commands defined in the project.json we saw earlier.

dnx web

aspnet5-dnx-web

As shown in the screenshot above, the web application is hosted at localhost:5000 by default. Indeed, we can confirm that this works by going there:

aspnet5-helloworld

The output we see comes from Startup.cs as we have seen earlier:

        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }

The Configure() method allows us to set up our web application pipeline. In here, we define any middleware we need. For example, if we want to use MVC, then we set it up here; but ASP .NET 5 does not assume that any such infrastructure is required by default. In this case, we are always giving a fixed response.

This is as far as I’m going to go with this little “Hello World” setup for ASP .NET 5. We haven’t even begun to see how different ASP .NET 5 is from the ASP .NET we have known so far. But hopefully, this article will save you a lot of frustration in setting things up until the tooling in Visual Studio 2015 catches up.

Messing Around with Tesseract OCR in .NET

This article describes software I’m not really familiar with. Take this with a pinch of salt. For all I know, tomorrow I may realize the error of my ways and change my tune.

I recently found out that there’s this open-source OCR software called Tesseract, and decided to give it a try. I’m going to show you how you can set up something really quickly, and some initial results I’ve seen.

First, install Tesseract via NuGet:

tesseract-nuget

Second, to use Tesseract’s OCR facility, you need some language data, which Tesseract provides. Go to the tessdata project and download it. Technically, you only need the files starting with eng* if you’re going to OCR English text. If you download the whole repo, be patient – it’s a few hundred megabytes zipped. Make sure you put the files in a folder called tessdata, or it won’t work.

Third, get yourself some test images you can feed to the OCR. You can find some online, or scan something from a book.

Fourth, you’ll need to add a reference to System.Drawing, because the Tesseract package depends on the Bitmap class:

tesseract-system.drawing

Finally, we can get some code in. Let’s use this (needs using Tesseract;):

        static void Main(string[] args)
        {
            Console.Title = "Trying Tesseract";

            const string tessDataDir = @"tessdata";
            const string imageDir = @"image.png";

            using (var engine = new TesseractEngine(tessDataDir, "eng", EngineMode.Default))
            using (var image = Pix.LoadFromFile(imageDir))
            using (var page = engine.Process(image))
            {
                string text = page.GetText();
                Console.WriteLine(text);
                Console.ReadLine();
            }
        }

This is enough to set up Tesseract, load a file from disk, and OCR it (convert it from image to text). It may take a few seconds for the processing to happen. Now, you may be wondering what a Pix class is, or what is a page. And I’m afraid I can’t quite answer that, because there doesn’t seem to be any documentation available, so that doesn’t exactly help.

So, when trying this out, I first scanned a page from The Pragmatic Programmer and fed it to Tesseract. I can’t reproduce that for copyright reasons, but aside from some occasional incorrect character, the results were actually pretty good.

The next thing I did was feed it the Robertson image from this page. It looked okay at first glance, until I actually bothered to check the result:

tesseract-robertson

Good heavens. What on Earth is a “sriyialeeeurreneeseenu”? Shocked by these results, I read some tips about improving the quality of the output. Because it’s true, you can’t blame the OCR for mistaking a ‘c’ for an ‘e’ when they look very similar, and the image has some noise artifacts (see top of image, where there’s some faint print from another page).

To make sure I give it some nice, crisp text, I took a screenshot of the Emgu CV homepage (shown below), and fed it to the program.

tesseract-emgucv-source

See the results for yourself:

tesseract-emgucv

That’s quite an elaborate mess. It may be because I’m new to this software, but that doesn’t give me a very good impression. Maybe it’s my fault. But I can’t know that if there’s no documentation explaining how to use it.

Simulating Probabilistic Behaviour

The source code for this article is available at the Gigi Labs BitBucket repository.

Let’s say we have a game featuring in-game people (commonly referred to as NPCs). Any game worth its salt will have some form of artificial intelligence (AI) to bring those characters to life to some extent, even if they’re just aimlessly wandering around.

To do this in C# using plain ASCII art, we can start out with the following code, which shows a cutesy ASCII face in the middle of the console window:

            int x = 40;
            int y = 12;
            const char person = (char) 2;
            const int delay = 1000;

            Console.Title = "Probabilistic Behaviour";
            Console.CursorVisible = false;

            while (true)
            {
                Console.Clear();
                Console.SetCursorPosition(x, y);
                Console.Write(person); // show character

                // TODO movement code goes here

                Thread.Sleep(delay);
            }

This is what you should see after running the code:

probabilistic-behaviour-start

Now, to make our character wander around randomly is pretty easy. First, declare a Random instance near the top of the program:

            var random = new Random();

Then, just replace the “TODO” comment with the following:

                int direction = random.Next(0, 4); // [0, 3]

                switch(direction)
                {
                    case 1: x--; break;
                    case 2: x++; break;
                    case 3: y--; break;
                    case 4: y++; break;
                }

You should now see the ASCII guy going around randomly. That’s all well and good, but you should realise that this is a uniform distribution: each outcome is just as likely as any other.

Sometimes, that’s not what you want. For example, let’s say you want the following to happen:

  1. 20% of the time, the character will go left.
  2. 10% of the time, the character will go right.
  3. 20% of the time, the character will go up.
  4. 50% of the time, the character will go down.

We could represent the above with the following hardcoded logic:

                double direction = random.NextDouble(); // 0 <= direction < 1

                if (direction >= 0 && direction < 0.2)
                    x--;
                else if (direction >= 0.2 && direction < 0.3)
                    x++;
                else if (direction >= 0.3 && direction < 0.5)
                    y--;
                else
                    y++;

That works, and you’ll see the ASCII guy tend to move downwards more than any other direction. But how can we extend this into a generic utility that can accept various different configurations?

It helps if, rather than considering individual probabilities per action, we stack them on top of each other and consider a cumulative probability:

Action Probability Cumulative Probability
Left 0.2 < 0.2
Right 0.1 < 0.3
Up 0.2 < 0.5
Down 0.5 < 1

Stacked on top of each other by probability, the actions would look something like this:

probabilistic-behaviour-cumulative

In this case we only need to take a random sample between 0 and 1, and see where in the above stack it lands.

To facilitate this, let us first declare a ProbabilisticAction class, which represents the mapping between a probability and an action. I’m assuming we don’t need to return anything; if we do, it’s easy to turn this into a generic class.

    public class ProbabilisticAction
    {
        public double Probability { get; set; }
        public Action Action { get; set; }

        public ProbabilisticAction(double probability, Action action)
        {
            this.Probability = probability;
            this.Action = action;
        }
    }

Back in our Main(), we can declare a list of such mappings to represent the scenario we had earlier:

            var actions = new List<ProbabilisticAction>()
            {
                new ProbabilisticAction(0.2, new Action(() => x--)),
                new ProbabilisticAction(0.1, new Action(() => x++)),
                new ProbabilisticAction(0.2, new Action(() => y--)),
                new ProbabilisticAction(0.5, new Action(() => y++)),
            };

We then pass these mappings, along with our Random instance, into a new class we’ll declare next:

            var actor = new ProbabilisticActor(actions, random);

The ProbabilisticActor encapsulates the logic for determining the next action. First, we store the mappings and the Random passed in at the constructor:

    public class ProbabilisticActor
    {
        private List<ProbabilisticAction> probabilisticActions;
        private Random random;

        public ProbabilisticActor(List<ProbabilisticAction> probabilisticActions,
            Random random)
        {
            this.probabilisticActions = probabilisticActions;
            this.random = random;
        }
    }

To avoid confusion, we also want to ensure that the probabilities passed in actually add up to 1:

        public ProbabilisticActor(List<ProbabilisticAction> probabilisticActions,
            Random random)
        {
            if (probabilisticActions == null)
                throw new ArgumentNullException(nameof(probabilisticActions));
            if (probabilisticActions.Select(mapping => mapping.Probability).Sum() != 1.0)
                throw new ArgumentException("Probabilities must add up to 1!");

            this.probabilisticActions = probabilisticActions;
            this.random = random;
        }

Now, we can actually add the logic that picks the next action to execute. This is done by taking a random sample and seeing where it falls in the probability space:

        public void DoNextAction()
        {
            double sample = random.NextDouble();

            foreach(var mapping in probabilisticActions)
            {
                double probability = mapping.Probability;
                sample -= probability;

                if (sample <= 0)
                {
                    var action = mapping.Action;
                    action();
                    break;
                }
            }
        }

All we have left is to replace the logic in Main() with a call to this new method:

            while (true)
            {
                Console.Clear();
                Console.SetCursorPosition(x, y);
                Console.Write(person); // show character

                actor.DoNextAction();

                Thread.Sleep(delay);
            }

If we run the program now, we can see our ASCII guy just as southbound as before:

probabilistic-behaviour-southbound

But unlike before, we now have an abstraction of the logic we originally hardcoded, and we can reuse it for all sorts of random behaviours.

In fact, this approach is not really about game AI at all. I’ve found it really useful when writing test harnesses that needed to simulate a user randomly interacting with an application, where different actions weren’t equally as likely to occur. This is just a simple demonstration, but it is easy to build more sophisticated logic on top of this approach.

Block Selection and Column Editing

We’re all very much used to selecting text by clicking and dragging the mouse. But by pressing the Alt key while doing that, you can select a rectangular block. This feature has been around since Visual Studio 2010 – part of it even since Visual Studio 2008 – and it’s available in most modern text editors such as Notepad++. However, most people seem not to be aware of this, which is why I’m writing this article.

Let’s say you created a new Console Application in Visual Studio, and added a few variables within the Program class:

    class Program
    {
        int name;
        int age;
        int address;

        static void Main(string[] args)
        {
            
        }
    }

Oops. Main() can’t access them, because it is static, and they are not. We’re going to have to make them static as well.

Now we can add the static keyword to each variable, one by one. Or, we can place the cursor before the first int, press Alt, click and drag downwards to create a sort of blue cursor that spans multiple lines. It’s a bit hard to see, so I’ve zoomed in a bit here:

column-editing-1

With that, we’ve enabled column editing. This means that whatever you type will now be written in multiple lines:

column-editing-2

You can use this to comment lines in bulk (similar to the Ctrl+K+C or Ctrl+E+C shortcuts, depending on your editor settings):

column-editing-3

Now, column editing is actually a special case of block selection with a width of zero. To see how block editing works, let’s change our variable names to the following:

        static int personName;
        static int personAge;
        static int personAddress;

Now, due to changing requirements, we decided that these shouldn’t be called person*, but customer*. Given that the variable names are nicely aligned underneath each other, we can press Alt, click and drag around person on all three lines, and we’ve made a block selection:

block-selection-1

Press Backspace to remove person from all three lines. The block collapses to zero width, so we’re back to column editing, and we can now easily write customer on all three lines:

block-selection-2

So there you go. Block selection and column editing are nothing new, but they’re very handy and good to know about.

A Gentle Introduction to Gulp

We’re at the end of 2015, and web technology has changed quite  a bit since I started in 2002. Nowadays, for the front end stuff, there is a whole family of tools based on the node.js package manager (npm) that you can use to streamline and automate your workflow.

In this article (based on Windows), we’ll learn to use Gulp to do routine tasks such as concatenating and minifying JavaScript tasks. There’s another tool called Grunt with a similar purpose, and you’ll find all sorts of discussions on the internet comparing Grunt vs Gulp. Basically, Grunt is the older of the two and has a bigger community – an important factor considering that these tools are plugin-driven. However, I’m covering Gulp here as I felt it was more intuitive. For this small demonstration it has all the plugins we need, and performance (a common point of comparison) isn’t even a factor.

Setting up Gulp

The first thing we need is to install node.js:

install-nodejs

There’s a chance you might already have node.js, if you installed it with Visual Studio 2015.

Once you have installed node.js, you should have npm in your path. Open a command prompt, and install Gulp using the following command:

npm install gulp -g

-g means globally, and thanks to this, gulp should now be in your path.

Next, we want to create a package.json file. This is a kind of project file for node.js-related stuff. We can use npm for this too:

npm init

npm will ask a bunch of questions in order to set up the package.json file, suggesting possible answers where it makes sense to do so. name and version are required, but you can leave the rest empty if you like:

npm-init

Next, we need to install Gulp locally in our project:

npm install gulp --save-dev

This installs Gulp; –save-dev updates the package.json with a devDependencies field:

{
  "name": "gulptest",
  "version": "1.0.0",
  "description": "Learning to use Gulp.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Daniel D'Agostino",
  "license": "ISC",
  "devDependencies": {
    "gulp": "^3.9.0"
  }
}

Plugins and the Gulp file

Gulp itself doesn’t do anything; it is just configured to run tasks. Its capabilities come from the plugins you install, and you configure it to do stuff using a Gulp file. For this simple example, we’re just going to use a few plugins:

npm install gulp-concat gulp-uglify --save-dev

Once again, –save-dev updates your devDependencies in package.json:

  "devDependencies": {
    "gulp": "^3.9.0",
    "gulp-concat": "^2.6.0",
    "gulp-uglify": "^1.5.1"
  }

Next, create a file called gulpfile.js, and put the following code in it:

var gulp = require('gulp'),
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat');
    
gulp.task('default', function() {
  return gulp.src('js/*.js')
    .pipe(concat('all.js'))
    .pipe(gulp.dest('dist/'));
});

To test this out, I downloaded jquery and jquery-ui, and put the uncompressed Javascript files in a “js” folder. Having created the Gulpfile above, all you need is to run Gulp:

gulp

You should find a folder called dist, with a file called all.js in it, containing the contents of the files originally in the js folder:

gulp-concat

Concatenating JavaScript is good for performance because the browser only needs to make a single request, rather than having to retrieve several small files. But we can do even better by minifying the JavaScript (using the gulp-uglify plugin). Just add the following line:

var gulp = require('gulp'),
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat');
    
gulp.task('default', function() {
  return gulp.src('js/*.js')
    .pipe(concat('all.js'))
    .pipe(uglify())
    .pipe(gulp.dest('dist/'));
});

Run Gulp again, and you’ll find that all.js has been updated. In fact, it’s much smaller now, and it’s completely illegible:

gulp-uglify

Conclusion and Further Reading

The purpose of this article was to get you set up with Gulp, and see something working with the least possible hassle. Mark Goodyear’s article (on which this article is partly based) covers a lot of other common operations to carry out with Gulp. If you need to do anything particular – linting your JavaScript files, minifying your CSS, using Less, etc, there’s probably a plugin for it.

Beyond that, all you need to know is how to use Gulp effectively as part of your build process.

  • Running Gulp without arguments makes it look for the “default” task. You can pass the name of a task to run as an argument, allowing you to run a variety of operations.
  • How do you debug your minified JavaScript? You don’t. Use separate tasks for development and for release, and minify only in your release task.
  • Ideally these tasks should be run automatically as part of your continuous integration.
  • An ASP .NET 5 (formerly known as vNext) project in Visual Studio 2015 can easily integrate with npm tools, and you can configure it to run your tasks when you build.
  • Not using Windows? These command line tools are easy to use on other platforms (although installing npm will obviously be different).

Update 8th January 2016: Check out “More Gulp in Practice“, the followup to this article.

Elements of Football Management in Software

My recent return to playing Sensible World of Soccer is not just fun. After all, team management has been happening in the football scene for far longer than the software industry has even existed. There is some serious stuff we can learn there.

So after three successful seasons that turned Hibernians (a local team that most people have never even heard of) into a winner of all the major football leagues, I decided to take up managing Partizani Tirana, the team that won the Albanian Premier Division, but that is similarly crap on an international level (at least in the game).

I could have remained managing Hibernians, now a stellar team, for the fourth season. But while it is enjoyable to win, the real challenge (and fun) is in watching people grow; learning their strengths and weaknesses, and putting them in the right formation so that they can work together with synergy. As for the old team, it is my aspiration in all aspects of life to leave things better than I found them, and my old boss certainly didn’t mind decorating his shelves with the trophies I won:

english_001

This funny guy is my new boss in the game:

english_002

And this is my new team:

english_003

I don’t know these guys, and I don’t know how they play. So how can I effectively manage them?

The first thing you need to do to manage a team is to learn their strengths and weaknesses, i.e. what they’re good at, and what they need to improve. So after playing a few matches with this team, I can learn about their skills: who are the fast guys, who have the best ball control, etc.

Everyone can be useful. If one of the attackers is not great at finishing, for instance, he can have a supporting role for the other attacker. The trick is in finding the right role for each team member so that they can be useful to the team.

While you can often make adjustments within the team to address weaknesses, sometimes this is not enough. For instance, with Hibernians, buying a fast midfielder with great ball control gave a great boost to the team. He would support attackers in offensive strategy, run back to help defenders by intercepting opponents, and basically go everywhere to support the functioning of the team.

This midfielder is an example of a playmaker. The playmaker is essentially a visionary, a strategist, and a catalyst for the team to achieve its goals. The playmaker is not necessarily in a leading role. But he is respected because he makes things happen; he brings the team towards success, and also helps it get through the tougher situations.

Software teams are not very different. Developers come from all sorts of backgrounds, and have different skills and comfort zones. The manager who takes the time to learn about their abilities will be in a strong position to allocate his resources where they are best focused.

Playmakers in software are sometimes called catalysts (as in the wonderful anecdote in the Peopleware book). Whether they have a leadership role or not, they play an important part in helping teams to gel, solving complex problems, working on essential infrastructure, and formulating the technological vision of the team.

Managing software teams may be something that appeared over the past few decades, but in many ways it’s not very different from team management in general. Looking at older disciplines such as football allows us to gain insight into management as a whole, and they can very well serve as analogies for what we do in software.