Tuesday, December 24, 2019

SQL Server–Activate Memory Optimized tables

When trying to create a Memory Optimized table in SQL Server, I got the following error message:

Cannot create memory optimized tables. To create memory optimized tables, the database must have a MEMORY_OPTIMIZED_FILEGROUP that is online and has at least one container.

To fix this I first had to add a new memory optimized filegroup to the database:

ALTER DATABASE OntSessionTmp ADD FILEGROUP ontsessiontmp_mod CONTAINS MEMORY_OPTIMIZED_DATA

After creating the filegroup I had to link a container:

ALTER DATABASE ontsessiontmp ADD FILE (name='ontsessiontmp_mod1', filename='F:\Program Files\Microsoft SQL Server\MSSQL13.ONTINST2\MSSQL\DATA\ontsessiontmp_mod1') TO FILEGROUP ontsessiontmp_mod

Now I could switch a table to a Memory Optimized version. Yes!

Monday, December 23, 2019

Install .NET Core 3.1 SDK on Ubuntu 18.04 inside WSL

I’m a big fan of WSL (Windows Subsystem for Linux) to test my .NET Core applications on Linux.

Recently I tried to install the .NET Core 3.1 SDK on my Ubuntu distribution inside WSL:

bawu@ORD02476:~$ sudo apt-get install dotnet-sdk-3.1

Reading package lists... Done

Building dependency tree

Reading state information... Done

E: Unable to locate package dotnet-sdk-3.1

E: Couldn't find any package by glob 'dotnet-sdk-3.1'

E: Couldn't find any package by regex 'dotnet-sdk-3.1'

This didn’t seem to work. He couldn’t find the .NET Core 3.1 SDK inside the package manager.

I first tried to refresh the packages list:

bawu@ORD02476:~$ sudo apt update

0% [Connecting to archive.ubuntu.com] [Connecting to security.ubuntu.com]

Hit:1 http://archive.ubuntu.com/ubuntu bionic InRelease

Get:2 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]

Get:3 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]

Get:4 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]

Get:5 http://archive.ubuntu.com/ubuntu bionic/universe amd64 Packages [8570 kB]

Get:6 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [593 kB]

Get:7 http://security.ubuntu.com/ubuntu bionic-security/main Translation-en [194 kB]

Get:8 http://security.ubuntu.com/ubuntu bionic-security/restricted amd64 Packages [15.1 kB]

Get:9 http://security.ubuntu.com/ubuntu bionic-security/restricted Translation-en [4684 B]

Get:10 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [627 kB]

Get:11 http://security.ubuntu.com/ubuntu bionic-security/universe Translation-en [210 kB]

Get:12 http://security.ubuntu.com/ubuntu bionic-security/multiverse amd64 Packages [6120 B]

Get:13 http://security.ubuntu.com/ubuntu bionic-security/multiverse Translation-en [2600 B]

Get:14 http://archive.ubuntu.com/ubuntu bionic/universe Translation-en [4941 kB]

Get:15 http://archive.ubuntu.com/ubuntu bionic/multiverse amd64 Packages [151 kB]

Get:16 http://archive.ubuntu.com/ubuntu bionic/multiverse Translation-en [108 kB]

Get:17 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [817 kB]

Get:18 http://archive.ubuntu.com/ubuntu bionic-updates/main Translation-en [288 kB]

Get:19 http://archive.ubuntu.com/ubuntu bionic-updates/restricted amd64 Packages [24.1 kB]

Get:20 http://archive.ubuntu.com/ubuntu bionic-updates/restricted Translation-en [6620 B]

Get:21 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [1033 kB]

Get:22 http://archive.ubuntu.com/ubuntu bionic-updates/universe Translation-en [319 kB]

Get:23 http://archive.ubuntu.com/ubuntu bionic-updates/multiverse amd64 Packages [9284 B]

Get:24 http://archive.ubuntu.com/ubuntu bionic-updates/multiverse Translation-en [4508 B]

Get:25 http://archive.ubuntu.com/ubuntu bionic-backports/main amd64 Packages [2512 B]

Get:26 http://archive.ubuntu.com/ubuntu bionic-backports/main Translation-en [1644 B]

Get:27 http://archive.ubuntu.com/ubuntu bionic-backports/universe amd64 Packages [4028 B]

Get:28 http://archive.ubuntu.com/ubuntu bionic-backports/universe Translation-en [1856 B]

Fetched 18.2 MB in 27s (661 kB/s)

Reading package lists... Done

Building dependency tree

Reading state information... Done

131 packages can be upgraded. Run 'apt list --upgradable' to see them.

But this didn’t made any difference:

bawu@ORD02476:~$ apt search dotnet-sdk

Sorting... Done

Full Text Search... Done

The trick is to first let the package manager know that it should include packages from ‘packages.microsoft.com’:

bawu@ORD02476:~$ wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb

bawu@ORD02476:~$ sudo dpkg -i packages-microsoft-prod.deb

Selecting previously unselected package packages-microsoft-prod.

(Reading database ... 28645 files and directories currently installed.)

Preparing to unpack packages-microsoft-prod.deb ...

Unpacking packages-microsoft-prod (1.0-ubuntu18.04.2) ...

Setting up packages-microsoft-prod (1.0-ubuntu18.04.2) ...

If we now update the package manager, it reads the packages from Microsoft as well:

bawu@ORD02476:~$ sudo apt-get update

Hit:1 http://archive.ubuntu.com/ubuntu bionic InRelease

Hit:2 http://archive.ubuntu.com/ubuntu bionic-updates InRelease

Get:3 https://packages.microsoft.com/ubuntu/18.04/prod bionic InRelease [4003 B]

Hit:4 http://archive.ubuntu.com/ubuntu bionic-backports InRelease

Hit:5 http://security.ubuntu.com/ubuntu bionic-security InRelease

Get:6 https://packages.microsoft.com/ubuntu/18.04/prod bionic/main amd64 Packages [85.1 kB]

Fetched 89.1 kB in 14s (6320 B/s)

Reading package lists... Done

And finally we find the .NET Core SDK when searching for packages:

bawu@ORD02476:~$ apt search dotnet-sdk

Sorting... Done

Full Text Search... Done

dotnet-sdk-2.1/bionic 2.1.802-1 amd64

  Microsoft .NET Core SDK 2.1.802

dotnet-sdk-2.1.105/bionic 2.1.105-1 amd64

  Microsoft .NET Core SDK - 2.1.105

dotnet-sdk-2.1.200/bionic 2.1.200-1 amd64

  Microsoft .NET Core SDK - 2.1.200

dotnet-sdk-2.1.201/bionic 2.1.201-1 amd64

  Microsoft .NET Core SDK - 2.1.201

dotnet-sdk-2.1.202/bionic 2.1.202-1 amd64

  Microsoft .NET Core SDK - 2.1.202

dotnet-sdk-2.1.300-preview2-008533/bionic 2.1.300-preview2-008533-1 amd64

  Microsoft .NET Core SDK 2.1.300 - Preview

dotnet-sdk-2.1.300-rc1-008673/bionic 2.1.300-rc1-008673-1 amd64

Microsoft .NET Core SDK 2.1.300 - rc1

dotnet-sdk-2.2/bionic 2.2.402-1 amd64

  Microsoft .NET Core SDK 2.2.402

dotnet-sdk-3.0/bionic 3.0.101-1 amd64

  Microsoft .NET Core SDK 3.0.101

dotnet-sdk-3.1/bionic 3.1.100-1 amd64

Microsoft .NET Core SDK 3.1.100

Friday, December 20, 2019

Delete a Windows Service

I’m so spoiled on using TopShelf that I don’t know anymore on how to remove a Windows Service the old fashioned way.

If you have Powershell 6 or higher, you can do the following:

Remove-Service –name “Your Service Name”

An alternative is to directly use the Service Control Manager:

sc.exe delete "Your Service Name"

Don’t forget the ‘.exe’ when invoking the Service Control Manager inside a Powershell command window.

More information: https://docs.microsoft.com/en-us/dotnet/framework/windows-services/how-to-install-and-uninstall-services

Thursday, December 19, 2019

RedisTimeoutException - High ‘in’ value

While investigating a performance issue we noticed that the we had a lot of RedisTimeoutExceptions inside our logs:

2019-12-15 16:26:57.425 +01:00 [ERR] Connection id "0HLS1E3OEP520", Request id "0HLS1E3OEP520:0000001D": An unhandled exception was thrown by the application.

StackExchange.Redis.RedisTimeoutException: Timeout performing PEXPIRE CookiesStorageAuthSessionStore-4a07a1bb-04e0-442d-9223-e1612967bf2b, inst: 2, queue: 8, qu: 0, qs: 8, qc: 0, wr: 0, wq: 0, in: 14411, ar: 0, clientName: SERVER1, serverEndpoint: Unspecified/redis:6379, keyHashSlot: 4822 (Please take a look at this article for some common client-side issues that can cause timeouts: http://stackexchange.github.io/StackExchange.Redis/Timeouts)

You would think that this indicates there is a performance issue in Redis but this turned out not to be the case.

Let’s have a second look at the error message and especially the strange parameters: inst: 2, queue: 8, qu: 0, qs: 8, qc: 0, wr: 0, wq: 0, in: 14411, ar: 0

In this situation you have to notice the high ‘in’ value. This value tells us how much data is sitting in the client’s socket kernel buffer.  This indicates that the data has arrived at the local machine but has not been read by the application yet.

So the problem should not be found inside Redis but in the application(or server) that is consuming Redis.

Wednesday, December 18, 2019

OpenLayers - Use SVG icons for markers

On one of my projects we are using OpenLayers to visualize geographical data. I got stuck when I tried to show markers on a map by using SVG icons.
My first attempt looked like this:


But on the map I only got a weird black triangle.😕

I tried a lot of alternatives but nothing made any difference. In the end I found out that I could fix it by specifying a size(width and height) inside my SVG file:


Remark: Changing the scale and size properties on the style seems to have no affect when using SVG’s. So make sure to set an appropriate size in the SVG file.

Tuesday, December 17, 2019

Disable transformations in ASP.NET Core

By default when you add a web.config file to an ASP.NET Core application, the config file is transformed with the correct processPath and arguments.

This can be quite annoying especially if you want to apply some web config transformation magic.

Inside the documentation, I found that you can prevent the Web SDK from transforming the web.config file by setting the <IsTransformWebConfigDisabled> property in the project file:

This disabled the web config transformation behavior but didn’t solve the problem that Visual Studio updated the web.config file.

A colleague sent me another (undocumented?) flag <ANCMPreConfiguredForIIS> :

Remark: This setting only works when you are running in IIS InProcess.

Monday, December 16, 2019

Change password in another domain

As a consultant I’m active at multiple clients. For each of these clients I get a domain account to be able to login onto their systems. But as they all enforce a password policy, I have to update a lot of passwords every month(thank god that password managers exists).

Here is a quick tip of you want to change the password of an Active Directory account but your PC isn’t part of the same domain:

You can still change your password if your PC is able to talk to the domain controller:

  • Hit CTRL-ALT-DELETE
  • Select Change a Password
  • You’ll see the Change a Password screen where the focus is on the old Password field. But what is not immediately obvious is that you can change the username(and domain!) in the first field. By setting here a different username you can change the password directly for any account you have access to.

Friday, December 13, 2019

Transport Tycoon exercises for DDD

While searching something on Github I stumbled over the following repo: https://github.com/Softwarepark/exercises/blob/master/transport-tycoon.md

This is a set of Domain-Driven Design (DDD) exercises. They take place in the universe of the Transport Tycoon. It is a game "in which the player acts as an entrepreneur in control of a transport company, and can compete against rival companies to make as much profit as possible by transporting passengers and various goods by road, rail, sea and air."

If you want to learn about DDD, or practice your DDD skills this is a great way to start…

Thursday, December 12, 2019

ASP.NET Core - Load session state asynchronously

While browsing through the ASP.NET Core documentation I noticed the following section: Load session state asynchronously.

The default session provider in ASP.NET Core loads session records from the underlying IDistributedCache backing store asynchronously only if the ISession.LoadAsync method is explicitly called before the TryGetValue, Set, or Remove methods. If LoadAsync isn't called first, the underlying session record is loaded synchronously, which can incur a performance penalty at scale.

To have apps enforce this pattern, wrap the DistributedSessionStore and DistributedSession implementations with versions that throw an exception if the LoadAsync method isn't called before TryGetValue, Set, or Remove. Register the wrapped versions in the services container.

To avoid this performance penalty, I created 2 extensions methods that do a LoadAsync before reading or writing the session state:

Wednesday, December 11, 2019

Autofac–Configure Container in .NET Core WorkerService

.NET Core 3.0 introduced a new WorkerService template that can be used as a starting point for long running service apps. As the worker service template didn’t use a Startup.cs file like in a traditional ASP.NET Core application, it wasn’t immediately obvious to me where I had to configure my IoC container.

So a quick tip for my future self, you can do this using the ConfigureContainer() method on the HostBuilder:

Remark: The example above is using Autofac but the approach is similar for other containers.

Tuesday, December 10, 2019

NuGet Restore error - Response status code does not indicate success: 401 (Unauthorized)

When trying to build a project in Visual Studio, it failed while downloading the nuget packages from our internal Azure Artifacts nuget store.

In the logs I could find the following error message:

C:\Program Files\dotnet\sdk\3.0.100\NuGet.targets(123,5): error : Failed to retrieve information about 'Example.WebApi.Client' from remote source 'http://tfs:8080/tfs/DefaultCollection/_packaging/892779dc-d854-4c9f-8b26-833d52585ae6/nuget/v3/flat2/example.webapi.client/index.json'. [C:\Projects\MapSU\MapSU.Server.sln]

C:\Program Files\dotnet\sdk\3.0.100\NuGet.targets(123,5): error :   Response status code does not indicate success: 401 (Unauthorized). [C:\Projects\MapSU\MapSU.Server.sln]

Directly accessing the Azure Artifacts url worked without a problem, but when I tried to do this through Visual Studio or through the commandline it failed with the error above.

I was able to solve the problem by removing the ‘vscredentials’ in the Windows Credentials manager that referred to the tfs server:

  • Open the search bar in windows and search for Credentials Manager
  • Click on Manage Windows Credentials.
  • In the Credential Manager go to ‘Windows Credentials’
  • Scroll to the list of Generic Credentials. Click on the vscredentials one and click on Remove.

Now try to access Azure Artifacts again in Visual Studio. This time I got a login popup, after entering the correct credentials everything worked again.

Monday, December 9, 2019

HTTP Error 500.35 - ANCM Multiple In-Process Applications in same Process

After switching one of our ASP.NET Core applications from out-of-process hosting to InProcess hosting, we got the following error message:

This is caused by the fact that we are running multiple applications in IIS in the same application pool. As long as we were running out-of-process this was not an issue. But when we switched to InProcess hosting it turned out that you cannot run multiple In-Process applications in the same application pool.

The solution is simple, give each application its own app pool.

Friday, December 6, 2019

.NET Core 3 - Minibook

The people from InfoQ released a free (mini)book about .NET Core. In this book, five authors talk about the current state of .NET Core 3.0 from multiple perspectives. Each author brings their experience and ideas on how different .NET Core 3.0 features are relevant to the .NET ecosystem, both present and future.

It covers the following topics:

  • Navigating the .NET Ecosystem - In 2002, .NET was released. Over the next 12+ years, the .NET developer community patiently grew at a seemingly steady pace. Then, things started evolving rapidly. Microsoft anticipated the changing ecosystem and embraced the open-source development mindset, even acquiring GitHub.
  • Interview with Scott Hunter on .NET Core 3.0 - Chris Woodruff talks to Director of Program Management for the .NET platform Scott Hunter about what developers can expect from .NET Core 3.
  • Single Page Applications and ASP.NET Core 3.0 - Web development has changed in the past few years, with the maturity of Angular, React, Vue, and others. We’ve moved from building web pages to building apps. We’ve also been shifting from rendering markup on the server to more commonly rendering it directly in the browser. But as developers continue to transition to client-side development, many are asking if they should still be using ASP.NET.
  • Using the .Net Core Template Engine to Create Custom Templates and Projects - The tooling story changed dramatically with .NET Core, because of its serious emphasis on the command line. This is a great fit for .NET Core's cross-platform, tooling-agnostic image.
  • Angular & ASP.NET Core 3.0 - Deep Dive - While there are many advantages to using Angular for building SPAs, some parts including trivial, static content such as Contact As, Licensing, etc. don’t need the extra complexity. In this article Evgueni Tsygankov shows how to build reusable Angular components that can be hosted in ASP.NET Core pages, allowing you to choose the right tool for each page.

Remark: Registration is required before you can download the ebook.

SQL Server–Find biggest tables

Did you know it is really easy to find out which tables in SQL Server use the most disk space?

  • Open SQL Server Management Studio
  • Right click on your database
  • Go to Reports –> Standard Reports

  • Choose the Disk Usage by Table report:

Thursday, December 5, 2019

ASP.NET Core - Using IClaimsTransformation with Windows Authentication

In ASP.NET Core you can implement the IClaimsTransformation interface. This allows you to extend/change the incoming claimsprincipal:

Unfortunately my ClaimsTransformer was never invoked when I used Windows Authentication in IIS.

The trick was to explicitly specify the IISServerDefaults.AuthenticationScheme:

Wednesday, December 4, 2019

Running ElasticSearch in Docker–Memlock check

While updating my docker-compose file  to the latest docker images, I noticed I had to set some extra values before I could run my ELK cluster:

I had to add an extra bootstrap check:

- "bootstrap.memory_lock=true"

and set the memlock ulimits:

ulimits:
    memlock:
        soft: -1
        hard: –1

The memory lock setting will disable swapping out parts of the JVM heap to disk. Memory swapping is bad for performance and node stability so it should be avoided at all cost.

More information: https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration-memory.html

The memlock soft and hard values configures the range of memory that ElasticSearch will use. Setting this to –1 means unlimited.

Tuesday, December 3, 2019

Publish a .NET Core app using Azure Pipeline

To publish a .NET Core application using Web Deploy, you can use the .NET Core Task inside Azure pipelines.

Through the .NET Core Task you can invoke the dotnet CLI and invoke the available commands. To use Web Deploy you can use the ‘Publish’ command.

It took me some time to find the correct arguments, so here they are in case you need it:

dotnet publish --configuration $(BuildConfiguration) /p:PublishProfile=$(BuildConfiguration) /p:Password=$(WebDeployPassword) /p:Username=$(WebDeployUser) /p:AllowUntrustedCertificate=True

Remark: Don’t forget to first create a PublishProfile(pubxml) file in Visual Studio and commit it to your repo. Git ignored my pubxml by default and it took me some time to figure out why nothing happened…

Monday, December 2, 2019

EditorConfig - Let private fields start with an underscore

I find code consistency really important. This removes a lot of mental burden from the developer.

One of the conventions that is quite common in C#is to use camelCase for local variables and _camelCase for private or internal fields.

An example:

Unfortunately this convention is not automatically enforced by Visual Studio. To fix this you can add an editorconfig file with the following rules:

dotnet_naming_rule.instance_fields_should_be_camel_case.severity = suggestion
dotnet_naming_rule.instance_fields_should_be_camel_case.symbols = instance_fields
dotnet_naming_rule.instance_fields_should_be_camel_case.style = instance_field_style
 
dotnet_naming_symbols.instance_fields.applicable_kinds = field
 
dotnet_naming_style.instance_field_style.capitalization = camel_case
dotnet_naming_style.instance_field_style.required_prefix = _