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!