Friday, November 30, 2018

SignalR - CORS error

After updating SignalR my program started to fail with the following error message:

Access to XMLHttpRequest at 'http://localhost:22135/chat/negotiate?jwt=<removed the jwt key>' from origin 'http://localhost:53150' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

To fix it I had to update the CORS policy by adding the AllowCredentials() method:

Thursday, November 29, 2018

Breaking changes when updating SignalR TypeScript client

Tuesday I blogged about some breaking changes when updating the SignalR backend in ASP.NET Core. Later on I noticed I had to do some changes on the frontend as well:

From:

To:

Wednesday, November 28, 2018

ElasticSearch Integration Testing with ElasticSearch Inside

Integration Testing can be quite cumbersome, especially when you have a lot of moving parts involved. To test my ElasticSearch code I was used to spin up a docker instance and discard it after the tests ran.

Recently I changed my approach after receiving the following tip from a colleague(thanks Jasper!): https://github.com/poulfoged/elasticsearch-inside 

ElasticSearch Inside is  a fully embedded version of Elasticsearch for integration tests. When the instance is created both the JVM and Elasticsearch itself is extracted to a temporary location and started. Once disposed everything is removed again. And despite what you may think, this happens really fast(a few seconds on my machine).

How to

  • Install the Nuget package:

Install-Package elasticsearch-inside

  • After that you have to create a new instance of the ElasticSearch class and wait for the Ready() method.
using (var elasticsearch = new Elasticsearch())
{
    await elasticsearch.Ready();
}
  • Now you can call the ElasticSearch instance using NEST:
using (var elasticsearch = new Elasticsearch())
{
    await elasticsearch.Ready();
    var client = new ElasticClient(new ConnectionSettings(elasticsearch.Url));

    var result = client.Ping();
}

Tuesday, November 27, 2018

Breaking changes when updating SignalR for .NET Core

I had to do some changes to one of our applications and noticed that it was still using the beta release of SignalR. So I thought it would be a good idea to quickly do an update to the release version. There were some breaking changes I was able to fix quite easily:

From:

To:

From:

To:

From:

To:

From:

To:

Monday, November 26, 2018

GraphQL–DotNet–Nullable types: Nullable<> cannot be coerced to a non nullable GraphQL type

I’m spending a lot (read: “waaay to many”) time learning GraphQL. One of the things I had to figure out was how to use nullable types inside my GraphQL schema.

By default when you use a nullable type inside your GraphQL schema, you get the following error message:

ArgumentOutOfRangeException: Explicitly nullable type: Nullable<DateTime> cannot be coerced to a non nullable GraphQL type.

To fix this, you have to expliclity specify the field as nullable in you GraphQL type definition:

Friday, November 23, 2018

GraphQL–DotNet - The type: Guid cannot be coerced effectively to a GraphQL type

I’m spending a lot (read: “waaay to many”) time learning GraphQL. One of the things I had to figure out was how to use Guids inside my GraphQL schema.

On one of my projects we are using Guids. Here is the mapping I tried to use:

When loading my GraphQL endpoint this resulted in the following error message:

The type: Guid cannot be coerced effectively to a GraphQL type

To fix it I had to explicitly specify the FieldType as IdType:

Thursday, November 22, 2018

GraphQL–DotNet–Expose exceptions

I’m spending a lot (read: “waaay to many”) time learning GraphQL. One of the things I had to figure out was how to expose exceptions. Out of the box you get a generic GraphQL exception, but if you want to drill down into what is going on, you have to change some configuration:

I’m using https://github.com/graphql-dotnet/server to serve my ASP.NET Core GraphQL endpoint. When configuring the middleware you have to add a specific setting to activate exception details:

GraphQL-DotNet–Use an async resolver

I’m spending a lot (read: “waaay to many”) time learning GraphQL. One of the things I had to figure out was how to call an async method inside a field resolver.

You have 2 options:

  • Option 1 -  Use the Field<> method and return a Task:
  • Option 2 – Use the FieldAsync<> method and await the result:

Tuesday, November 20, 2018

Angular-oauth2-oidc: Error validating tokens. Wrong nonce.

After integrating the Angular-oauth2-oidc library in our application, we got the following error message when invoking the Implicit Flow:

Error validating tokens. Wrong nonce.

This is the code we were using:

Problem is that the loadDiscoveryDocument is a promise and we didn’t await for the result. As a consequence the nonce from the first request(loadDiscoveryDocumentAndTryLogin) is overwritten by the second request(initImplicitFlow) causing the error above.

To fix it we have to chain the requests together:

Friday, November 16, 2018

F#–Write your own Excel in 100 lines of code

I’m a big F# lover. I really fell in love with the density and expressiveness of the language. Today I noticed the following blog post where Tomas Petricek wrote an Excel variant in about 100 lines of F# code. Truly impressive!

Go check out the blog post here; http://tomasp.net/blog/2018/write-your-own-excel/ and have a look at the completed code here; https://github.com/tpetricek/elmish-spreadsheet/tree/completed

image

Thursday, November 15, 2018

ELK stack–Getting started

Yesterday Elastic announced the new releases of their product suite.

Here is the general announcement; https://www.elastic.co/blog/elastic-stack-6-5-0-released and here are the announcements for the specific products:

Best way to try out the new features is by using the available Docker images at https://www.docker.elastic.co/

To help you getting started I created a docker-compose file that combines ElasticSearch, Kibana and APM: https://github.com/wullemsb/elasticgettingstarted/blob/master/docker-compose.yml

Wednesday, November 14, 2018

Learning PWA’s - Service Workies

Progressive Web Apps are evolving quite fast and Google is leading the initiative. At Chrome Dev Summit 2018 they reconfirmed the message that the future of PWA’s is looking great. With deeper OS integrations, improved speed and upcoming new capabilities, the gap between native and PWA will possible be closed faster than we think.

So time to start learning about PWA’s and no better way to learn something than through gamification. Dave Geddes, who created Flexbox Zombies and CSS Grid Critters, created a new learning game. Service Workies helps you understand Service Workers soup to nuts. The first chapter of the adventure is rolling out in beta now. Google partnered with Dave to make sure the full adventure can be free to all.

image

Tuesday, November 13, 2018

TFS Build SonarQube Error - SonarAnalyzer.dll could not be found

Got a call for help from a colleague who couldn’t get an Acceptance release out of the door. Problem was that the automated build responsible for packaging and deploying the Acceptance version failed. He asked me to take a look…

Inside the build logs we noticed the following error message:

2018-11-13T06:35:22.4133574Z (CoreCompile target) ->

2018-11-13T06:35:22.4133574Z   CSC : error CS0006: Metadata file 'D:\b\4\agent\_work\_temp\.sonarqube\resources\1\Google.Protobuf.dll' could not be found [D:\b\4\agent\_work\40\s\MTIL.Domain\MTIL.Domain.csproj]

2018-11-13T06:35:22.4133574Z   CSC : error CS0006: Metadata file 'D:\b\4\agent\_work\_temp\.sonarqube\resources\1\SonarAnalyzer.CSharp.dll' could not be found [D:\b\4\agent\_work\40\s\MTIL.Domain\MTIL.Domain.csproj]

2018-11-13T06:35:22.4133574Z   CSC : error CS0006: Metadata file 'D:\b\4\agent\_work\_temp\.sonarqube\resources\1\SonarAnalyzer.dll' could not be found [D:\b\4\agent\_work\40\s\MTIL.Domain\MTIL.Domain.csproj]

2018-11-13T06:35:22.4143340Z

This would make you think that there is something wrong with our SonarQube tasks. Would we an obvious reason right? The strange thing is that we weren’t using SonarQube on our Acceptance release build, so why did the build agent mentions something about SonarQube?

Chapter 1 - The story of the canceled build

After further investigation, I noticed that the problem started happening when another build was canceled. This build was using the same repository(but a different branch) to build our development release. And in this build we were using the SonarQube tasks. So maybe something wasn’t cleaned up correctly?

I killed the VBCSCompiler process (it was blocking some files in the _temp folder) and removed the _temp folder completely. This first seemed to work but after doing one build the problem reappeared.

Chapter 2 - The story of the other running build

So the story continues. I started to monitor the build server for other activities and noticed that the problem reappeared when a development build was running that was using the SonarQube tasks. When I tried to do an Acceptance build after the Development build completed, it succeeded without errors.

Our conclusion was that when another build was running on the same repo that was using the SonarQube tasks, it created some conflict that made the other build fail. Sounds like a bug to me?

As a workaround, we temporarily disable the Development build when we try to create an Acceptance build.

Monday, November 12, 2018

ASP.NET Core–Serve a default.html

Sometimes you lose waaay to much time on something that looks obvious once you find it. Today I was searching a solution to serve a default.html file when the root url was called in Asp.NET Core; e.g. http://mysamplesite/root/

I was first fiddling around with the StaticFiles middleware but couldn’t find a way. Turns out there is another middleware; DefaultFiles that handles this use case.

Just call the UseDefaultFiles method from Startup.Configure:

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

With UseDefaultFiles, requests to a folder search for:

  • default.htm
  • default.html
  • index.htm
  • index.html

The first file found from the list is served as though the request were the fully qualified URI. The browser URL continues to reflect the URI requested.

Remark: UseDefaultFiles must be called before UseStaticFiles to serve the default file.

More information: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-2.1

Friday, November 9, 2018

Azure DevOps–Aad guest invitation failed

When trying to invite a user from an external domain to Azure Devops, it failed with the following error message:

"Aad guest invitation failed"

image

What is going on?

Our Azure DevOps is backed by Azure AD(and synced with our internal AD). To invite the user, we’ll have to add him first to our Azure AD before we can add him as a guest to our Azure DevOps account.

Thursday, November 8, 2018

MassTransit - Increase the throughput of your consumers

While running some stress tests on our environment, I noticed that our queues started to fill up. When I took a look at our MassTransit consumers, they were processing 10 messages simultaneously but not more although the CPU on the server was not stressed at all.

What is going on?

The reason is due to the number of messages the RabbitMQ transport will “prefetch” from the queue. The default for this is 10, so we can only process 10 messages simultaneously. To increase this, we can do 2 things:

  1. Configure the prefetchcount for your endpoint using the PrefetchCount property on the IRabbitMqBusFactoryConfigurator class.
  2. Add a ?prefetch=X to the Rabbit URL.

Remark: As a general recommendation, PrefetchCount should be relatively high, so that RabbitMQ doesn't choke delivering messages due to network delays.

Wednesday, November 7, 2018

MassTransit–Fault events vs Error Queues

Something that was kind of confusing for me was the relationship between MassTransit Fault<T> events and Error Queues.

When a MassTransit consumer throws an exception, the exception is caught by middleware and the message is moved to an _error queue (prefixed by the receive endpoint queue name). The exception details are stored as headers with the message.

image

I was thinking that the Messages were wrapped in a Fault<T> event before they were stored in the queue. But it turns out that they are unrelated.

What really happens is that in addition to moving the message to an error queue, MassTransit also generates a Fault<T> event. This event is either sent to a FaultAddress or ResponseAddress if present or the fault is published.

Tuesday, November 6, 2018

Entity Framework Core–Table per hierarchy

In my Entity Framework Core application I wanted to use the Table Per Hierarchy pattern. So I configured the EF mapping to use a discriminator column:

This didn’t had the desired effect. As I ran my application I got the following error message:

The entity type 'ForeignSupplier' is part of a hierarchy, but does not have a discriminator value configured.

Whoops! I forgot to specify how EF Core should recognize the different child types. Let’s fix this in our configuration:

Monday, November 5, 2018

Entity Framework Core - The EF Core tools version '2.1.1-rtm-30846' is older than that of the runtime '2.1.4-rtm-31024'.

When trying to create my initial migration using EF Core, I got the following error message:

Add-Migration InitialCreate

The EF Core tools version '2.1.1-rtm-30846' is older than that of the runtime '2.1.4-rtm-31024'. Update the tools for the latest features and bug fixes.

System.IO.FileLoadException: Could not load file or assembly 'Microsoft.EntityFrameworkCore.Relational, Version=2.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

File name: 'Microsoft.EntityFrameworkCore.Relational, Version=2.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'

   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c.<FindContextTypes>b__12_4(TypeInfo t)

   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()

   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()

   at System.Linq.Enumerable.ConcatIterator`1.MoveNext()

   at System.Linq.Enumerable.DistinctIterator`1.MoveNext()

   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()

   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.FindContextTypes()

   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.FindContextType(String name)

   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)

   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)

   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)

   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_1.<.ctor>b__0()

   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()

   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)

Could not load file or assembly 'Microsoft.EntityFrameworkCore.Relational, Version=2.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

At least this error message points me in the right direction. I opened up the Package Manager console and updated the Microsoft.EntityFrameworkCore.Tools nuget package:

Install-Package Microsoft.EntityFrameworkCore.Tools -Version 2.1.4

Friday, November 2, 2018

Serilog–How to enable Seq integration through config?

I’m a big fan of structured logging in general and Serilog in particular. Especially in combination with Seq it is unbeatable.

Today I lost some time searching how to specify the Seq log sink using configuration. Here are the steps I had to take:

  • Add the Serilog.Settings.Configuration NuGet package to your project(this one is for ASP.NET Core, others exists for web.config, …)
  • Create a LoggerConfiguration:
  • After that you can specify your configuration inside your appsettings.json: