Friday, May 31, 2019

Azure DevOps–Licensing changes

Good news for everyone who is using Azure DevOps; Microsoft is simplifying the licensing model. Most information about it can be found here;

I want to point out one change specifically as this was a show stopper for most of my customers who wanted to use Azure Artifacts:

For cloud-hosted Azure Artifacts, users will no longer need an Azure Artifacts extension license. Instead, users will only pay for what they store in Azure Artifacts. The first 2 GB are free, then prices range from $2 to $0.25 per GB per month, depending on the storage consumed.

Users with a Basic license will now be able to use Azure Artifacts on-premises without needing to purchase an Azure Artifacts extension. This means with Azure DevOps Server 2019 (formerly Team Foundation Server), users with a Basic License can create and consume Azure Artifacts on-premises if they have a Basic license assigned. Please note that for previous versions of our server product, an Azure Artifacts extension is still needed to access this functionality.

This means that you no longer need a separate license to start using Azure Artifacts which probably will increase adoption.

Friday, May 17, 2019

Entity Framework Core–Storing a string array

Starting from EF Core 2.1, storing a string array becomes possible thanks to the support for value conversions

Here is our Entity:

And here is the code we added in the OnModelCreating():

Thursday, May 16, 2019

Orleans–Codegen issue Error MSB3073 The command ""dotnet" "Orleans.CodeGeneration.Build.dll" ""Bots.orleans.g.args.txt"" exited with code 3.

Part of the magic inside Orleans happens through the usage of code generation. However when I tried to build my Orleans app it failed with the following error message:

Error MSB3073 The command ""dotnet" "C:\Users\UserName.nuget\packages\\2.1.0\build..\tasks\netcoreapp2.1\Orleans.CodeGeneration.Build.dll" "@C:\projects\myProjectName\_obj\Debug\Bots\netcoreapp2.1\codegen\Bots.orleans.g.args.txt"" exited with code 3. Bots C:\Users\UserName.nuget\packages\\2.1.0\build\Microsoft.Orleans.OrleansCodeGenerator.Build.targets 82

This error message  is not very useful, but it brought me to the following issue on GitHub:

I accidently downloaded and used the wrong NuGet package; I was using Microsoft.Orleans.CodeGenerator.Build where in fact I needed Microsoft.Orleans.CodeGenerator.MsBuild.

I don’t know exactly why both packages exists. Anyone?

Wednesday, May 15, 2019

Microsoft Orleans Grain Persistence using PostgreSQL

I didn’t found the documentation really clear on the steps involved when using Grain Persistence in combination with PostgreSQL.

So here is my attempt to describe the process:

    • Invariant should be set to ‘npgsql’
    • ConnectionString should be set to the connection to the PostgreSQL instance you want to use
    • UseJsonFormat should be set to true as PostgreSQL has good Json support.
  • Let your grain inherit from Grain<> and specify a state object:
  • Add a StorageProvider attribute on top of your Grain and set the name to the storage name you used inside the cluster config
    • In our example we had set this to ‘OrleansStorage’:
  • Execute the PostgreSQL-Main.sql and PostgreSQL-Persistence.sql scripts inside the OrleansAdoNetContent/PostgreSQL folder to create the necessary database objects
  • Now you are good to go!

Tuesday, May 14, 2019

Azure Data Studio - PostgreSQL error: Unhandled exception while executing query: 'dict' object has no attribute 'encode'

I started using Azure Data Studio a few weeks ago to talk to PostgreSQL and I must say that I do like it, especially when comparing it to PGAdmin. I had a few issues where I lost my connection, but a refresh always solved it so far.

Yesterday I stumbled over an error when trying to execute the following query:

When executing this query, it failed with the following error message:

Started executing query at Line 1

Commands completed successfully

Unhandled exception while executing query: 'dict' object has no attribute 'encode'

Total execution time: 00:00:00.138

The problem happens when I try to query the payloadjson column which contains a JSONB type. As a workaround I explicitly added a cast to JSON to the query:

More information:

Thursday, May 9, 2019

Windows Identity Foundation - Change cookie name

After authenticating through WIF, a FedAuth cookie is generated containing all your claims. We got a situation where this caused issues as the same cookie name was used for different applications. One FedAuth cookie was generated at the root level and was applicable for all sub sites. Every site generated it’s own FedAuth cookie that was applicable for that specific subsite only.

This caused conflicts when you navigate from one of the subsites to the root site. As a FedAuth cookie is found, it is used to try to extract the claims. But this doesn’t work as the cookie isn’t generated for this website.

To fix it, we changed the cookiename in the WIF configuration to use a different name and avoid name collisions:

Wednesday, May 8, 2019

Entity Framework Core–Change naming conventions for PostgreSQL

The default naming conventions for Entity Framework Core are quite annoying when using PostgreSQL. EF Core generates all databases objects using Pascal Casing, as a consequence you have to add quotes to all queries which exactly ain’t fun if you have to write some queries by hand.

Let’s update the naming convention to use snake_case which is what PostgreSQL expects.

Let’s start by adding a simple ToSnakeCase extension method:

Now it’s time to update our OnModelCreating method and change the naming convention:

That’s it!

Tuesday, May 7, 2019

GraphQL Birdseye

As the GraphQL ecosystem keeps growing, I continue discovering new tools. Recently I noticed GraphQL Birdseye, a tool that allows you to view any GraphQL schema as a dynamic and interactive graph.

Here is a live demo;

You can add graphql-birdseye as a Javascript package to your project:

Monday, May 6, 2019

PostgreSQL - Delete a database with active users

When trying to drop a database in PostgreSQL, it failed with the following error message:

11:32:15 AMStarted executing query at Line 1

database "sampledb" is being accessed by other users

Total execution time: 00:00:05.016

Whoops, seems that our database is still in use. Let’s kill all active connections

Let’s now try to execute the drop database again:

Friday, May 3, 2019

RxJS: Never subscribe in a subscription

During a code review of an Angular code base I noticed the following code snippet:

What’s wrong with this code?

We are subscribing inside a subscription. This makes it almost impossible to know what subscriptions are open at what moment. Good luck closing these subscriptions in the correct way(which you are doing, right?).

A solution is to rewrite this code to use only 1 subscription. Closing this subscription will automatically clean up all inner streams. Let’s apply some RxJS magic to fix this:

Thursday, May 2, 2019

The type 'StackExchange.Redis.IDatabase' exists in both StackExchange.Redis and StackExchange.Redis.StrongName.

After switching from the old packages.config file to the PackageReference inside my csproj file, I got the following error message when trying to build:

The type 'StackExchange.Redis.IDatabase' exists in both 'c:\packages\StackExchange.Redis.1.0.481\lib\net45\StackExchange.Redis.dll' and 'c:\packages\StackExchange.Redis.StrongName.1.0.481\lib\net45\StackExchange.Redis.StrongName.dll'

However when I looked at the referenced packages I only saw a package reference to StackExchange.Redis…

The problem was that the StackExchange.Redis nuget package was referenced both directly using a PackageReference and indirectly through a reference with the Microsoft.Web.RedisSessionStateProvider.

After removing the direct reference to StackExchange.Redis, the build error disappeared.