Skip to main content


Showing posts from September, 2019

ASP.NET Core 3.0–Swashbuckle error

As probably most people in the .NET ecosystem I’m using Swashbuckle to generate my OpenAPI documentation. (Anyone using NSwag instead?) After upgrading to ASP.NET Core 3.0 (and switching to the 5.0-rc4 prerelease version of Swashbuckle), the following code no longer compiled: I had to replace the Info class which couldn’t be found by the OpenApiInfo class: This OpenApiInfo class is now part of the Microsoft.OpenApi.Models namespace.

Setup the Kubernetes dashboard on Docker for Windows

A useful tool when you are new to Kubernetes is the Kubernetes Dashboard . Unfortunately the Kubernetes Dashboard is not included out-of-the-box with Docker for Windows however it can be easily setup for your local cluster. To setup the dashboard use the following command: kubectl apply -f The output should look like this: secret/kubernetes-dashboard-certs created serviceaccount/kubernetes-dashboard created created created deployment.apps/kubernetes-dashboard created service/kubernetes-dashboard created To view the Dashboard in your web browser run: kubectl proxy And nagivate to your Kubernetes Dashboard at: http://localhost:8001/api/v1/namespaces

Switch between Kubernetes contexts

Lost some time yesterday figuring out how to switch between different Kubernetes environments. So a quick post, just as a reminder for myself: You can view contexts using the kubectl config command: kubectl config get-contexts CURRENT  NAME                            CLUSTER                    NAMESPACE            *         docker-desktop                   docker-desktop             docker-desktop                                              docker-for-desktop               docker-desktop             docker-desktop You can set the context by specifying the context name: kubectl config use-context docker-for-desktop

ElasticSearch–Performance testing

When trying to load test our ElasticSearch cluster, we noticed big variations in results that we couldn’t explain based on the changes we made. Turned out that our tests were not executed in comparable situations as we didn’t clear the ElasticSearch cache. So before running our tests, we cleared the cache using following command: POST /<myindexname>/_cache/clear?request=true If you want to view what’s inside the Elastic node cache, you can use the following command:: GET /_cat/nodes?v&h=id,name,queryCacheMemory,queryCacheEvictions,requestCacheMemory,requestCacheHitCount,requestCacheMissCount,flushTotal,flushTotalTime

GraphQL Rules

As with every technology you give to your team everyone has different opinions and conventions. A style guide becomes an indispensible part of your development organisation. Otherwise the ‘tabs vs spaces’ discussion can go on forever. This also applies to GraphQL. So to help you get started take a look at . Rules and recommendations mentioned here were the results of 3 years' experience of using GraphQL both on the frontend and backend sides. We also include the recommendations and experience of Caleb Meredith (PostGraphQL author, Facebook ex-employee) and Shopify engineers. This guide is intended to be open source and could change in the future, - the rules may be improved on, changed, or even become outdated. What is written here is a culmination of time and pain suffered from the use of horrible GraphQL-schemas.

Cannot create or delete the Performance Category 'C:\Windows\TEMP\tmp3DA0.tmp' because access is denied.

After migrating some .NET applications from an old server to a brand new Windows Server 2019 instance, we stumbled over a range of errors. Yesterday we got one step closer to a solution but we are not there yet. The application still doesn’t work but now we get the following error message: Server Error in '/AppServices' Application. Cannot create or delete the Performance Category 'C:\Windows\TEMP\tmp3DA0.tmp' because access is denied. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.UnauthorizedAccessException: Cannot create or delete the Performance Category 'C:\Windows\TEMP\tmp3DA0.tmp' because access is denied. ASP.NET is not authorized to access the requested resource. Consider granting access rights to the resource to the ASP.NET req

Access to the registry key 'Global' is denied.

After migrating some .NET applications from an old server to a brand new Windows Server 2019 instance, we stumbled over a range of errors. Here is the first error we got: Server Error in '/AppServices' Application. Access to the registry key 'Global' is denied. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.UnauthorizedAccessException: Access to the registry key 'Global' is denied. ASP.NET is not authorized to access the requested resource. Consider granting access rights to the resource to the ASP.NET request identity. ASP.NET has a base process identity (typically {MACHINE}\ASPNET on IIS 5 or Network Service on IIS 6 and IIS 7, and the configured application pool identity on IIS 7.5) that is used if the application is not impersonating

Microsoft Orleans - Configure .NET garbage collection

To increase the performance of your Orleans application it is important that you tweak the .NET garbage collection settings. According to the documentation the best settings is a combination of gcServer=true and gcConcurrent=true . This can be done inside your csproj file by adding the following lines: <PropertyGroup> <ServerGarbageCollection>true</ServerGarbageCollection> <ConcurrentGarbageCollection>true</ConcurrentGarbageCollection> </PropertyGroup> Remark: If the changed settings are not picked up immediately, deleting the bin/ and obj/ folders can help. (As mentioned here )

Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

After introducing the dynamic keyword in my .NET core codebase, the project failed to compile with the following error message: Error      CS0656 Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create' SOFACore.Messaging              C:\Projects\SOFACore\SOFACore.Messaging\MessagingModule.cs     To fix it I had to add the Microsoft.CSharp nuget package. This package is necessary to use the C# dynamic data type in a .NET Standard library.

Learning GraphQL

Even Microsoft is jumping on the GraphQL bandwagon. On Channel 9 you can find a new series on GraphQL: Intro to GraphQL, Part 1 Intro to GraphQL, Part 2 : Exploring a GraphQL endpoint Creating a GraphQL Server, Part 1: Building a GraphQL server with Apollo GraphQL Creating a GraphQL Server, Part 2: Publishing a GraphQL Server to Azure App Service Creating a GraphQL Server, Part 3: Publishing a GraphQL Server to Azure Functions

Principled GraphQL

In case you didn’t notice it yet, I’m a big fan of GraphQL. It solves so many problems when dealing with an ever growing list of devices and (micro)services. The people who created Apollo distilled their experiences into a set of best practices for creating, maintaining, and operating a data graph. INTEGRITY PRINCIPLES 1. One Graph 2. Federated Implementation 3. Track the Schema in a Registry AGILITY PRINCIPLES 4. Abstract, Demand-Oriented Schema 5. Use an Agile Approach to Schema Development 6. Iteratively Improve Performance 7. Use Graph Metadata to Empower Developers OPERATIONS PRINCIPLES 8. Access and Demand Control 9. Structured Logging 10. Separate the GraphQL Layer from the Service Layer A must read for every GraphQL enthousiast!

ElasticSearch - Exposing your ElasticSearch instance

ElasticSearch is safe out-of-the-box. If you do a new installation, your ElasticSearch instance is only listening to internal traffic. If you want to make the ElasticSearch API’s accessible outside the VM where you installed it, you have to take some extra steps: Go to the ElasticSearch folder that you configured to store your index and configuration data. Open the ElasticSearch.yml file inside the config folder. Set the value to a non-loopback address. I’ll use but a specific IP address is of course better: If you know restart your ElasticSearch instance, you’ll notice that we are not there yet. The node fails to start with the following error message: [2019-07-10T14:34:59,782][INFO ][o.e.d.DiscoveryModule    ] [ESSRV1] using discovery type [zen] and seed hosts providers [settings] [2019-07-10T14:35:00,436][INFO ][o.e.n.Node               ] [ESSRV1] initialized [2019-07-10T14:35:00,436][INFO ][o.e.n.Node   

Azure DevOps Server–Error publishing nuget packages

As part of our build process we package and push a set of nuget packages to our artifacts repository. Recently we made the switch to Azure Artifacts after which uploading packages started to fail with the following error message: The nuget command failed with exit code(1) and error(Response status code does not indicate success: 409 (Conflict - The feed already contains ‘ExceptionHandling.Database 6.4.1'. (DevOps Activity ID: CAEC4462-2E20-4C69-9AFE-3BBC3C961E20)).) Packages failed to publish Ok, it seems that Azure Artifacts doesn’t like it when you try to upload the same packages multiple times. (We bumped the package version manually and didn’t care about overwriting an existing package so far). Can we fix this? We are using the NuGet task . This task has an interesting option: ‘Allow duplicates to be skipped’. Let’s try this… Unfortunately we ended up with the same error message as above. Let’s take a look at the documentation: If you continually publish

ElasticSearch - Cache aggregations and suggestions

A quick tip for everyone using ElasticSearch(aren’t you all?); It can be a good idea to separate the search request that fetches the results from the search request that returns the aggregations or suggestions . Why would you do that? Caching of course! On each shard the request cache module caches the local search results. But(!) by default the request cache module only caches the results of search requests where size=0 .  This means that it only works when you don’t want any hits returned. We tested it on our development cluster and the difference in performance is significant. More information:

XUnit - Async lifetime

The setup of your test context in XUnit is typically done through the constructor. For context cleanup, you can add the IDisposable interface to your test class, and put the cleanup code in the Dispose() method. But what if your setup/teardown logic contains some async methods? It would certainly be an anti-pattern to add this code inside your synchronous constructor or Dispose. The correct way to do this in XUnit is through the IAsyncLifetime interface: This interface provides you an async alternative to manage the lifetime of your test context.  It can be used inside your test classes directly but also works in Class and Collection fixtures .

Team Foundation Server–402 (Payment Required)

As part of our build process we push some of our artifacts as NuGet packages to Team Foundation Server. After adding a new build agent, executing the push failed with the following log output: 2019-09-02T13:30:07.1191540Z ##[section]Starting: dotnet push 2019-09-02T13:30:07.1191540Z ============================================================================== 2019-09-02T13:30:07.1191540Z Task         : .NET Core 2019-09-02T13:30:07.1191540Z Description  : Build, test, package, or publish a dotnet application, or run a custom dotnet command. For package commands, supports and authenticated feeds like Package Management and MyGet. 2019-09-02T13:30:07.1191540Z Version      : 2.131.0 2019-09-02T13:30:07.1191540Z Author       : Microsoft Corporation 2019-09-02T13:30:07.1191540Z Help         : [More Information]( ) 2019-09-02T13:30:07.1191540Z =========================================================

FluentValidation–Validating collections

On one of my projects we are using FluentValidation. After upgrading to FluentValidation 8 the way we had to validate our collections changed. Before we were using this: Now we had to use the RuleForEach method: But what if you also want to validate if the collection itself is empty or not. This is still possible through RuleFor:

Entity Framework Core Query Objects

Although the name suggests otherwise you are not limited to using entity types (=objects with an id) in EF Core. EF Core 2.1 introduces support for query types , which can be used to query data that isn’t mapped to entity types. This allows you to directly map your query results to DTO’s, something especially useful on the query side when you are having a CQRS style architecture. Let’s try this! First we have to create our DTO: Next step is to make EF Core aware of the existence of this query type. We’ll use the fluent configuration api but instead of calling the Entity<T>() method on the modelBuilder we’ll use the Query<T>() method: Next, we configure the DbContext to include the DbQuery<T> : You can then define queries directly in OnModelBuilding using a LINQ query through ToQuery(): Of course you can also map a query type to a view using ToView(): A last option is to directly map it to a raw SQL query using the FromSql method on your DbContex

NSubstitute Roslyn Analyzers

Quick tip if you are using NSubstitute (like me) as your mocking library. Certainly don’t forget to include the NSubstitute Roslyn analyzers as well. This allows you to detect some cases where NSubstitute will fail at runtime (e.g. when you attempt to mock non-virtual members). For the full list of rules that are validated, take a look at the documentation:

.NET Memory management posters

If you finally want to be able to answer the dreaded “explain memory management in .NET” interview question, I have a solution for you… Take a look at the .NET Memory Management posters created by Konrad Kokosa: