Thursday, August 31, 2017

Visualizing Git commands

While preparing a training about Git and it’s infinite list of commands, I discovered http://git-school.github.io/visualizing-git/. This is a great help to explain some of the Git concepts and visualize the effect of the different commands.

Let’s try the tool to demonstrate the concept of a rebase.

  • We start by creating a second branch and adding some commits to both master and the second branch:

image

  • Now while sitting on the sample branch, we execute the git rebase master command to rebase our current branch(sample) onto master. Thanks to the visualization tool we see that our commits are replayed on the master branch resulting in new commit ids.

image

  • As a last step, we still have to merge these changes on the master branch.

image

Really nice way to learn Git!

Wednesday, August 30, 2017

System.ValueTuple; we are not there yet

The introduction of System.ValueTuple makes using Tuples in .NET a lot more user friendly and fixes the mistake of making System.Tuple<> a reference type.

Creating a tuple becomes this easy:

Still there are some rough edges, for example what do you think will happen if I try to execute the following code:

Turns out that the ValueTuple has no built in support for equality checks:

image

In F# this works without a problem:

image

Tuesday, August 29, 2017

Angular: Set default headers on each request

Today I was discussing with a colleague what’s the best options to always set some header data for your HTTP requests. Here is my solution…

Create a new TypeScript class that inherits from BaseRequestOptions:

Note: In this example I injected a LOCALE_ID to capture the culture set in the application.

Next step is to create a provider that replaces the default RequestOptions:

Last step is to register the DefaultRequestOptionsProvider in your module:

Monday, August 28, 2017

Agile HR Blog series

As part of your organizational transformation towards Agile you cannot leave a department behind. This means that the way your HR department works and handles things like recruitment, hiring but also compensation and benefits should change as well.

Johanna Rothman shared a great set of posts about Agile HR:

A must read for every HR manager…

Friday, August 25, 2017

Deploying extra files when using WebDeploy

On one of the teams I’m coaching they are using Angular (4) in combination with ASP.NET Web API. This combination took a little more time to setup than for ASP.NET Core but worked quiet nice in the end.

In the current setup the Angular code is stored inside the ASP.NET Web API project:

image

To deploy the application to our servers, we configured a build process that contains the following steps:

  • Step 1 - Restoring the NuGet packages from our private package repository.
  • Step 2 – Compiling the .NET solution using MSBuild
  • Step 3 – Restore the NPM packages required for the Angular code
  • Step 4 – Execute the ng build command specify the environment and other parameters
  • Step 5 – Running the tests
  • Step 6 – Deploying the application using WebDeploy

image

After configuring all steps above, we noticed that everything was compiled nicely but after WebDeploy was completed only the C# assemblies were published on the web server. The files generated by Angular CLI were missing…

This makes sense as by default WebDeploy is only aware of the files that are tracked by the Visual Studio project inside the csproj file. To let WebDeploy know that some extra files need to be copied, we have to open up the .pubxml files and add some extra xml voodoo:

image

First add an extra target:

In this sample, we specify that we want to include all files in the dist folder and its subfolders(dist\**\*). The root of the folder is the same as the web project folder.

Second step is that we invoke this target before the web deploy file copy is executed or before the web deploy package is created:

That’s it!

Thursday, August 24, 2017

Open a Command Prompt from File Explorer

Small productivity tip I got from a colleague:

  • You have a specific folder opened in File Explorer and want to open up a Command Prompt at this location.

image

  • Type ‘cmd’ in the address bar and hit ‘ENTER’

image

  • A Command Prompt appears with the current folder already active

image

Wednesday, August 23, 2017

ASP.NET Core 2.0–Help, where is my Configuration?

In ASP.NET Core 1.x the Configuration was initialized in the Startup class:

If you create a new project in ASP.NET Core 2.0, your Startup class is almost empty and you cannot find any Configuration related code anywhere. Still if you run your application, the configuration is loaded and everything is working as expected.

So where is the magic?

The Configuration is no longer found in the Startup class but is loaded and executed from the Program.cs file where it is part of the WebHost.CreateDefaultBuilder method.

This method does a lot of stuff out-of-the box including loading configuration data from the following sources:

  • appsettings.json and appsettings.{environment}.json (e.g. appsettings.Development.json)
  • User secrets
  • Environment variables
  • Command-line arguments

This explains the magic. But what if you want to change this? No worries, you can use the ConfigureAppConfiguration method to change the configuration.

If you need the Configuration data in your Startup class, you can simply inject it through the constructor:

Tuesday, August 22, 2017

Using the Work Item Multivalue control in TFS 2017 (On premise)

Today one of my colleagues in our ALM team asked for help. For a customer we upgraded their TFS environment to TFS 2017. One of the changes we had to do along the way was replacing the existing MultiValue control by a newer version(https://github.com/Microsoft/vsts-extension-multivalue-control).

Multivaluecontrol

We followed the steps as mentioned here(https://github.com/Microsoft/vsts-extension-multivalue-control/blob/master/xmldetails.md) but the control didn’t appear.

Here is the template XML that we were using(I removed some content):

Although we couldn’t see any difference with the steps mentioned above, it didn’t work.

When I had a look I noticed that the extension is only registered in the WebLayout part of the Form.

Remark: In TFS you always had 2 layouts(a layout and a weblayout), the first one applies when opening a work item in Visual Studio or Test Manager, the weblayout applies when opening a workitem in the browser.

We first tried to add the extension to the layout part as well, but this didn’t work and resulted in some errors.

Then I had an idea, TFS 2017 offers a new Work Item experience. As mentioned here(https://www.visualstudio.com/en-us/docs/work/reference/weblayout-xml-elements) the WebLayout element is only applied on the new work item experience! This explains why our changes didn’t show up.

The new Work Item experience is an opt-in experience that should be enabled by a collection administrator. After enabling it, our Multivalue control appeared on the form…

Remark: For TFS 2017, the new form is automatically available when you add team projects to a new collection.

Monday, August 21, 2017

TFS - Maintaining your TFS Build Agents

After some time, your build agents start to eat up more and more disk space on your build server. Before I always cleaned it up manually when I get a warning from our system monitoring tools, but there is actually a better way I wasn’t aware of.

It is possible to schedule a Maintenance Job to clean up the _work folder in the agent:

image

Remark: As this has an impact on the availability of your pool it is recommended to limit the max percentage of agents running maintenance(25% by default).

Where can you find these setting?

  • Login to your TFS or VSTS portal
  • Open the Administration Section of the portal and go to the Agent Pools section

image

  • On the Agent Pools page, select a specific pool from the list of available pools

image

  • On the right choose the Settings tab

image

Friday, August 18, 2017

Tuples in C#7

One of the nice features in C#7 is the support for Tuples as a lightweight datastructure using the System.ValueTuple NuGet package. It simplifies your codebase where you had to fallback before to out parameters or arbitrary objects.

Let’s have a look at a simple example:

image

This sample shows how easy it is to return tuples from your methods. Only problem I have with this implementation is that if you try to access the output of this method call, you still see the Item1, Item2 properties which are not really meaningful:

image

You don’t have to stop there, we can update the method signature with some extra metadata:

image

If we now try to access the tuple values again, we see the following instead:

image

NOTE: The name associated with the tuple element is not a runtime metadata, i.e. there is no such a property/field with the name on the actual instance of that value tuple object, the property names are still Item1, Item2, etc., all element names are design time and compiler time only. If we decompile the code with JustDecompile, we see the following:

image

Notice the attribute generated on top of the code. This TupleElementNames attribute is picked up by Visual Studio and the compiler and provides the necessary intellisense. This guarantees that it also works when you import this DLL into another project…

Thursday, August 17, 2017

Are your if statements not hidden sagas?

This video by Udi Dahan made me rethink all if statements in my code:

In the video Udi uses the following deceptive simple looking requirement as an example:

“Disallow the user from buying products that are no longer available.”

Doh! This must be the easiest requirement I’ve ever seen. Let’s implement it…

Ok, when the user goes to the products page and we show a list of products, let’s add an extra check that only shows the items who are not deleted from our product catalog:

if(item.state== States.Deleted)

///Filter item from list

Ok, perfect. Problem solved! But wait, what if the user leaves the pages open for a while and in the mean time the product gets removed from the catalog, what happens if the user tries to add this product to his shopping cart? Ok, let’s add an extra check when the user tries to add an item to his cart:

if(item.state== States.Deleted)

///Show warning to user that product is no longer available

Ok, perfect. Problem solved! But wait, what if the user adds some products to his cart, leaves his cart open for a while and in the mean time the product gets removed from the catalog, what happens if the user tries to checkout his order? Ok, let’s add an extra check when the user tries to checkout his cart:

if(item.state== States.Deleted)

///Show warning to user that product is no longer available

Ok, perfect. Problem solved! But wait, what if the user spends a few minutes searching for his credit card during the checkout process and and in the mean time the product gets removed from the catalog, what happens if the user pays for his order?

Wait! Stop! Let’s break up here. It becomes obvious that there is always a moment where the if check is just to late.

The problem is that we end up with a business oriented eventual consistency problem that is hard to solve. Turns out that these kind of ‘if statements’ get better removed and replaced by long running processes that can impact the domain in multiple places.

To return to our example, the moment we set the IsDeleted flag to true for a product in our database, we’ll start a long running process that checks all active shopping carts, remove the deleted item from the carts and display the user a message when he returns to your website and opens his shopping cart:

image

Wednesday, August 16, 2017

Chrome HTTPS error on localhost: NET::ERR_CERT_COMMON_NAME_INVALID

If you are a developer and are using a Self-Signed certificate for your HTTPS server, you recently may have seen the following error in Chrome(or a non-Dutch equivalent Winking smile):

image

Starting from Chrome 58 an extra security check got introduced that requires certificates specify the hostname(s) to which they apply in the SubjectAltName field. After they first introduced this change, the error message was not very insightfull but today if you take a look at the Advanced section of the error message or the Security panel in the Developer tools, you’ll get some more details pointing to the SubjectAltName issue:

image

image

Create a new self-signed certificate

To fix it, we have to create a new self-signed certificate. We can not use the good old makecert.exe utility as it cannot set the SubjectAltName field in certificates. Instead, we’ll use the  New-SelfSignedCertificate command in PowerShell:

New-SelfSignedCertificate `
    -Subject localhost `
    -DnsName localhost `
    -KeyAlgorithm RSA `
    -KeyLength 2048 `
    -CertStoreLocation "cert:CurrentUser\My" `
    -FriendlyName "Localhost certificate"
Now you have a new certificate with a correct Subject Alternative Name in your Personal certificate store:
image
Next step is to trust this certificate by moving it to the Trusted Root Authorities. You can either do this by hand using the certmgr tool in Windows or script it with Powershell as well:
# set certificate password here
$pfxPassword = ConvertTo-SecureString -String "YourSecurePassword" -Force -AsPlainText
$pfxFilePath = "c:\tmp\localhost.pfx"
$cerFilePath = "c:\tmp\localhost.cer"

# create pfx certificate
Export-PfxCertificate -Cert $certificatePath -FilePath $pfxFilePath -Password $pfxPassword
Export-Certificate -Cert $certificatePath -FilePath $cerFilePath

# import the pfx certificate
Import-PfxCertificate -FilePath $pfxFilePath Cert:\LocalMachine\My -Password $pfxPassword -Exportable

# trust the certificate by importing the pfx certificate into your trusted root
Import-Certificate -FilePath $cerFilePath -CertStoreLocation Cert:\CurrentUser\Root

Import it in IIS

OK, almost there. A last step to get it working in IIS is to import the pfx in IIS:

  • Open IIS using inetmgr.
  • Go to Server Certificates.

image

  • Click on the Import… action on the right. The Import certificate screen is shown.

image

  • Select the pfx, specify the password and click OK.
  • Now that the certificate is available in IIS, you can change the bindings to use it. Click on the Default Web site(or any other site) on the left.
  • Click on the Bindings… action on the right. The Site Bindings screen is shown.

image

  • Click on the https item in the list and choose Edit… . The Edit Site Binding screen is shown.

image

  • Select the newly created SSL certificate from the list and click OK.

Monday, August 14, 2017

Using F# in Visual Studio Code

If you are interested in F# and want to start using it inside Visual Studio Code, I have a great tip for you:

Have a look at the F# with Visual Studio Code gitbook. This contains a short guide that explains you step by step on how to get your Visual Studio Code environment ready for your first lines of pure F# magic.

image

Happy coding!