Blog of Web Developer Garry Pilkington

(ASP.Net, C#, AngularJs, JavaScript, HTML5 & UWP)

Wow what a title, but it does explain that this post covers debugging the full .net framework application (not .net core) running on a Server Core container (not Linux) from the comfort of a Windows 10 Pro machine running Visual Studio 2015 and Docker for Windows.

Running remote tools on a machine and attaching is a pretty straight forward task, but there a re a few hurdles in the way when doing it on Windows Server Core 2016 container, but once it is scripted it is pretty painless.

Firstly we need a decent Docker image to start with, luckily the guys at Microsoft have created the Microsoft/aspnet image we can start with so lets build up our dockerfile

FROM microsoft/aspnetRUN mkdir C:\site

This gets the base image and creates directory that we are going to use for our web files.

This section is completely optional and all it does is install the web management tools for remote administration. You may want to tweak the container settings such as application pool and start and stop it from the GUI on your Windows 10 machine. If you are not bothered about IIS settings, then you can omit this section.

This copies the directory permissions set up for the wwwroot directory and assigns it to the site directory, so we don’t end up with nasty permission denied issues.

EXPOSE 8000 8172 4020 4021

We need to expose 8000 for our web application, 8172 for remote IIS admin and 4020 and 4021 are the ports we need opening for remote debugging tools. Visual Studio 2015 remote tools use these ports, other versions use different ports and as yet I cannot find the ports for Visual Studio 2017.

Next we locate our dockerfile using a cmd prompt and run docker build

docker build -t iis-site .

It will take a while to run through and will be quicker in future builds as you will already have the layers that make up the final image.

This creates a container based on our previous iis-site image and creates a mapping to a directory on our Windows 10 machine to the site directory we created in the dockerfile; this container will have the name web1.

This gives me 172.19.184.110 and yours will be different as each container gets its own address. We know we are on port 8000 so open up a browser and browse to your home page:-

Great, now lets get debugging. In future releases of Visual Studio 2017 it will be possible to debug straight into a Windows container, but at the moment it is limited to Linux containers, so we need to do a bit more configuration.

Once downloaded, put the .exe in the same directory as your web application on your machine as that is already visible to the container. There are ways to automate the download using Invoke-WebRequest, but I had several issues with resolving the url so it was easier to do it myself.

Create a .bat file with the following and copy that also into the web application directory on your machine:-

rtools_setup_x64.exe /install /quiet

Get the id of the container by using the command:-

docker ps

With the id, lets open an interactive cmd prompt:-

docker exec -it 03a8eb766d5a cmd

Where 03a8eb766d5a is my container identifier.

Run the bat file:-

install-tools.bat

This will take a couple of minutes to run through, but when it is finished you can cd to the C:\Program Files\Microsoft Visual Studio 14.0\Remote Tools directory to take a look.

This will start the remote debugging service msvsmon and your cmd prompt will just sit quiet with no cursor.

So now open up the web application in Visual Studio and go to Debug >> Attach to process

Click on the Find button and it should find your container with its id and ip address showing, simply select it.

Now we need to make sure we choose Managed (v4.6, v4.5, v4.0) code or whatever version of the framework you are using. Also make sure show processes from all users is checked.

Scroll down and choose w3wp and attach. Check the security warning and then start debugging as you would normally do.

Ideally it would be best if the remote tools could be downloaded as part of the build and the starting of msvsmon be automatic when F5 in Visual Studio. If you are happy with your container, you could save it as an image using the command:-

When doing Continuous Integration and Continuous Deployment, sometimes its great to get your code into production but hidden from any end user actions. In this post I will outline what I have been using with great success on my SaaS application ObsPlanner. There are however loads of libraries and other tools that will do the same thing, but I opted for the more simple, home grown approach.

My application is an MVC application that uses Angular JS in the views to give a better end user experience by acting as a mini SPA, so C#, Razor and Angular need to know about what features are available and what is not.

The database structure is simple, a table with one column for the toggle name and another for if it is enabled like this:-

I am using Entity Framework for all my database work, so I have a FeatureToggleRepository that retrieves the data like this:-

Each of my MVC controllers inherit from a BaseController which has methods used throughout the site including the getting of toggles:-

Now each of my controllers can easily get the toggle list:-

Where the toggle list is added to a view model, in this case it includes the logged in user details as well as the toggles. So in the view I can use Razor to run a conditional against it like this:-

So that works great for the View, what about the Angular stuff, couldn't that break if certain elements are not present in the view? Well yes it could so in the JavaScript I simply have all my toggle code nicely wrapped in functions that only get called if an element with the correct id is present in the view like this:-

The setup for this site is a development, staging and live server all with their own copies of the database. So this method allows me to push code through the whole life cycle and simply switch on the feature on the live server when I am happy with it.

Require.js is a JavaScript module loader, helping to reduce complexity of applications by managing dependencies and allowing easier separation and organisation of code into modules.

Asynchronous Module Definition or AMD modules are a way for applications to manage dependencies and easier separation by organising code into modules. Require.js is one such AMD module loader that can be used with jQuery, node and others, but firstly the JavaScript needs to be refactored appropriately.

Run JSLint over the code

JSLint is a tool that can be run either from the command line, through Gulp or Grunt or even in the browser at https://www.jslint.com/, it will highlight issues with the JavaScript to be fixed that will produce better quality code.

Structure the JavaScript

After the issues highlighted by JSLint have been fixed, organise the code so that it follows a more structured outline such as having a collection of vars and functions.

Add the AMD define call

For it to be recognised by module loaders such as require.js, the code needs to be wrapped in define calls which will turn it into an AMD module.

Dependencies such as jQuery

To add any dependencies such as jQuery, simply include them in the define call array such as this:-

Add a little Encapsulation

One of the advantages of the module pattern is that it can be structured so that variables and functions can be internalised and effectively defined in a 'private' scope. The module's return object can define exactly what should be publicly accessible. In the previous code snippet, the variable foo and both functions were all returned by the module. This means that they would all be publicly accessible by any client code. Instead, we want to ensure that foo and the functions are initially defined as private, and then expose the functions explicitly in the return object.

Following on from the previous post where we already have a container that can run a static website inside IIS, this post will configure IIS to run a simple MVC website and deploy an application into it.

Setting up Containers for MVC Web Applications

So by calling Get-Container and Get-ContainerImage we should have our ServerCoreIIS container switched off and our 2 base images.

Firstly we are going to create a new container that will end up being our base image for MVC applications, so call the New-Container command like this:-

When it is done you will be back at the PowerShell prompt and you shouldn’t need to reboot the container.

Exit out of the PowerShell session and stop the container. Now we need to create an image from this container, so call the Get-Container and pipe it to the New-ContainerImage command similar to what we did in the last post:-

Now you have an image of Server Core with IIS and MVC that you can create all future containers from.

Deploy an MVC application to a container

You may have a different method of how to deploy an application to a container, but for simplicity for this exercise I have a network share that I have copied an out of the box Visual Studio MVC application into. So create a new container from the IISMvc image.

Creating an IIS Base Image for Containers

Now we have a base image from the last post, we can use it to create other images and containers. Enter a PowerShell command and call Get-ContainerImage, we should see our WindowsServerCore image.

For the sake of this demonstration we will let our containers get an IP address from DHCP in the network, other situations will lead to different DHCP configurations with the containers and their IP address as completely throw away.

So again in the host machine create a new VM switch, I have it mapped to my External switch which will handle the DHCP.

New-VMSwitch –Name DHCP –NetAdapterName Ethernet

Now we create a new container which will become our base IIS image, so call