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/aspnet
RUN mkdir C:\site

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

RUN powershell -NoProfile -Command \
    Import-module IISAdministration; \
    New-IISSite -Name "Site" -PhysicalPath C:\site -BindingInformation "*:8000:

This creates the web application in IIS and binds it to port 8000 and our path to the web files.

RUN powershell -NoProfile -Command \
    Install-WindowsFeature -Name Web-Mgmt-Service

RUN powershell -NoProfile -Command \
    New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WebManagement\Server -Name EnableRemoteManagement -Value 1 -Force

RUN powershell -NoProfile -Command \
    Get-Service -Name WMSVC

RUN powershell -NoProfile -Command \
    Set-Service WMSVC -startuptype "Automatic"
   
RUN powershell -NoProfile -Command \
    Start-Service -Name WMSVC

RUN powershell -NoProfile -Command \
    net user iisadmin P2ssw0rd /add

RUN powershell -NoProfile -Command \
    net localgroup administrators iisadmin /add

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.

RUN powershell -NoProfile -Command \
$acl = Get-Acl -Path "C:\inetpub\wwwroot";Set-Acl -Path "C:\site" -AclObject $acl;

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.

Now we have our image, lets run with it:-

docker run -d -p 94:94 -v "C:\Users\username\Documents\Visual Studio 2015\Projects\WebApplication4\WebApplication4":c:\site --name web1 iis-site

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.

Lets test this by finding the ip address:-

docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" 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:-

image

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.

We need to install the Remote Tools for Visual Studio 2015 so go here and download it.

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.

Exit out of the interactive session and get back to docker and run:-

docker exec -it 03a8eb766d5a "C:\Program Files\Microsoft Visual Studio 14.0\Common7\IDE\Remote Debugger\x64\msvsmon.exe" /nostatus /silent /noauth /anyuser /nosecuritywarn

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

debug-1

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

debug-2

debug-3

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.

debug-4

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:-

docker commit 03a8eb766d5a iis-debug-tools

Just remember to stop it first.

Happy coding.

Creating Controllers in Umbraco CMS

On a recent project I needed to implement a secure area on a public facing website that runs on Umbraco CMS.
Umbraco runs on top of ASP.Net MVC, so pretty much what you can do with ASP.Net MVC you can do with Umbraco. The key requirements for this small project were to create a secure area that allows users to register for an account and login. Also the registered users were to be given different roles one for the uploading of documents and the other for the download of the same documents.

image

As MVC implements the membership provider, it was possible to create a register form which uses the same provider. In the view instead of using Html.BeginForm, for Umbraco we use Html.BeginUmbracoForm()

All this method does is acknowledge the registration and send out an email to the admin staff who then validates the request offline. One they have done this they will manually create a member in the Umbraco back office. Members in Umbraco can belong to either the Member type or a custom type. For our implementation we created a Portal Member Type that has all the same properties as the Member type except for an additional Portal Admin property. Members that are a Portal Admin are allowed to upload documents to the secure area; all other members are read only in essence.

image

So when the admin staff adds a new Member they choose the Portal Member Type.

Then simply add the necessary details and save.

image

Now that the user has an account to login they can go back to the same page and enter their credentials.

Which when posted sends required parameters to the controller.

This controller inherits from the Umbraco SurfaceController which allows it do either a standard redirect or a RedirectToCurrentUmbracoPage() for invalid attempts.
This method simply uses the Membership.ValidateUser() method which does the lookup in the database for the user.

Once the redirect has been complete, the call into the Index method of the GovernorPortalController occurs which inherits from the Umbraco RenderMVCController class. This class allows the Index method to be overridden and so a model can then be passed to the calling view. In our implementation we simply go to a backend database to get a collection of document details that are stored in a custom table in SQL Server. The controller then passes that collection to a ViewBag that the view then iterates through.

For some reason that I am yet to work out, the recommended way to implement custom controllers in Umbraco is to override RenderMVCcontroller for GETs and override SurfaceController for POSTs.

Anyway that aside, Admin Portal users need to upload documents to this area so another form is added to the same view. This is again using the Html.BeginUmbracoForm() helper method that posts to the UploadController's UploadFileMethod taking in an HttpPostedFileBase and title string parameters.

image

After checking this file's ContentLength, it is then saved to the server file system while being saved with a GUID for its filename to stop conflicts.

Various properties are then saved to the database, in this example I am using a simple SqlCommand instead of using Entity Framework as nowhere else in the site is using EF.

Once a collection of documents is presented to the user, admin users can delete documents by the use of a conditional that checks their role; this is found by querying the Umbraco properties for the user.

Happy coding.

Offline Web Applications

The HTML 5 specification, now available in most evergreen web browsers, gave the power of offline web applications. How this works is a manifest file is downloaded to the client which lists all files needed to make that page useable even if there is no network connection. This manifest file canm include JavaScript, CSS and HTML files. Of course it is possible to create an ASP.Net MVC application that can use this same technique as it renders HTML 5 anyway, however there are a few gotchas to look out for which I will cover in this post. Firstly the path to the .manifest file needs to be included in the HTML element at the top of the page.
<html lang="en" manifest="offline.manifest">
manifest file
For an MVC site, simply add the reference to the manifest in the _Layout file and add each resource you want in the browser application cache.
 
These resources above are used for the standard MVC template you get with Visual Studio 2015.
Now to get IIS to serve up this offline.manifest file you either have to add a mime type on the server or add it to the <system.webserver> element in web.config.
Its important that you add the clear element and you need then to add the usual types your site will serve up other wise you will get an HTTP 500 on each of these.
In Chrome when browsing to this page you can examine the Application Cache by going to the developer tools (F12) and going to the Resources tab.
1
Make sure that the 'Disable cache' check box is cleared as by default it is checked when you open up the developer tools and the browser will not retrieve the files needed from the cache.
2
Now by switching off your network connection or setting the Network throttling drop down to Offline (I disable my network card temporarily for a full test), your website should still view correctly and as the JavaScript has also been cached, it should function the same as well.
3
The main issue with the .manifest file is the browser does not know when the contents listed in it have changed unless the time stamp on the manifest itself has changed. One way to do this is to version the file and an even better way is to version it by using your application build number.
There are many issues with MVC serving up a .manifest file and the easiest solution I have found is to write out a physical file to the location the site is hosted in like this.
Which can be placed inside the Home/Index controller. Then add the path to the _Layout file like this.


<html lang="en" manifest="/Manifest/offline.manifest">


You will need to add write permissions to this directory for the IIS account so it can delete and write the file. Now if your build number increments each time you do a build and deploy, the manifest file will be regenerated and the client browser will pick up any changes.


Happy coding
 

There has been quite a lot written lately about the MEAN stack which is MongoDB, Express, Angular and Node, but I am going to describe the architecture I have used to create ObsPlanner.com. It comprises of both the MEAN stack and ASP.Net, Web.API, SQL Server as well as a number of third party components.

About ObsPlanner.com

The ObsPlanner.com website is a web application aimed at the more technical amateur astronomer market. It allows the user to plan in advance what astronomical objects they wish to observe by taking into account obstructions such as buildings and then optimises the plan around the times the user is at the telescope. Plans can then be downloaded and loaded into telescope controlling software which will automate the plan. Future releases will also include a mobile/offline mode and maybe even control the scope itself via Bluetooth. But that is dependent on much more research.

This is a brief overview of the architecture I chose.

ObsPlanner schematic

 

ASP.Net MVC Razor Views

By using Razor views, I could quickly create all the views for the front end based on layouts. Also with Razor and MVC I had a security model that could validate the user and redirect them if they were not authenticated or authorized to go to that view.

Angular js

Each view has an angular controller to manage its data binding and any service calls to either the Node or Web.API layers. By using angular it was possible to create a neatly structured code base as well as giving the end user a fast UI experience.

ASP.Net MVC & Web.API

With ASP.Net MVC and Web.API I was able to utilize the forms based security model as well interface with the Entity Framework layer that manages all the relational data from SQL Server. The services also use token based authentication which was very easy to set up using MVC Filters and attributes.

Node js & Express

As the site has a large amount of math based calculations, I wanted to use a language and technology that took this responsibility away from the client machine as I couldn’t guarantee what inconsistencies would be introduced. So I opted to use node.js so previously written components in JavaScript could be re-used with little change. It is running on IIS using the IISNode plugin and neatly interfaces with MongoDB using Express.

Entity Framework (EF)

I used a code first approach to create the entities that are relational in nature so the SQL Server database could be dropped and re-generated as the model changed. I also used the repository and Unit of Work patterns which lead to a faster integration with the MVC and Web.API controllers.

SQL Server

This is the data store for more relational entities such as the user and location as well as account stores. I was happier choosing this instead of having all data in Mongo as I was familiar with the security side of things and I wanted to use entity framework, repository and unit of work patterns.

MongoDB

I chose this as part of the back end for a fast read only data store that easily and quickly integrates with Node and Express. All the astronomical data is stored in this database and is made up of multiple collections for thousands of celestial objects. By using a data store that manages json natively it was very easy to retrieve astronomical data and pass it to the front end in the same format that the angular controllers could manage.

Stripe

As ObsPlanner is a multi tiered application, I wanted an easily integrated payment system without having to worry about being compliant with the banking systems. Stripe has an easy to use API layer that can be used both as part of the front end layer as well as the middle tier layer written in C#. When a user does opt to move on to the Pro level, none of the card details go through the ObsPlanner system and only to Stripe systems.

SendGrid

There are a number of internal subsystems which need to manage the sending of messages to registered users, this is done by SendGrid whichhas a simple API and allows access to message statistics such as errors, opening rate etc.

All this is running on one instance of Windows Server 2008 R2, not ideal I know but it is all I can afford just now.

So that is a quick run down of the architecture of ObsPlanner.com as of February 2016. It may change in the coming months as more users register and I detect any pain points.

Happy coding

 

It seems in light of revelations surrounding security of websites that there are more and more sites utilizing HTTPS instead of HTTP. The older reasons not to adopt HTTPS such as the burden on server and client processors has pretty much dissapeared. There is no real reason not to implement HTTPS and if you want to use protocols such as SPDY or HTTP/2 then you have to enforce a secure connection. To do this in an MVC project you have to do a few things, firstly add a filter to the GlobalFilterCollection like this:-

 

 

This code implements the RequireHttpsAttribute and allows through http connections if it is running on localhost which is ideal for a development team that doesn’t want to start messing arround with certificates.

Then you need to edit the web.config, again in a dev environment you can get away with creating transforms that will add the security side of things when you do a publish under that configuration.

The main points in the above code are the requireSSL attributes and the customHeaders element of system.webServer. The Strict-transport-Security custom header enforces HSTS which tells the browser to only connect on HTTPS and never on HTTP; this helps prevent such attacks as cookie hijacking.

In Chrome dev tools you should see this in the Response header:-

Strict-Transport-Security:max-age=16070400; includeSubDomains

Where the max-age is how long the browser will connect over HTTPS for; Twitter for example sets a max age of 20 years to prevent any attack on their servers circumventing HTTPS.