Tuesday, January 23, 2018

TFS Build Error CS1617: Invalid option 'latest' for /langversion; must be ISO-1, ISO-2, Default or an integer in range 1 to 6

After setting the Language version to C# latest minor version for my project, our TFS build started to fail with the following error message:

Error CS1617: Invalid option 'latest' for /langversion; must be ISO-1, ISO-2, Default or an integer in range 1 to 6

image

While looking through the build logs I noticed that the build server was still using MSBuild v14 instead of 15. I first thought that my build agents were not up to date, so I triggered an upgrade: http://bartwullems.blogspot.be/2017/09/team-foundation-serverupgrade-your.html

clip_image001

This made no difference, the used build tasks were not able to discover the newer version of MSBuild on the build server as they didn’t use VSWhere.exe yet.

In the end I decided to do an upgrade of TFS(a TFS 2017 instance) to TFS 2017 Update 3. After doing that, a new version of the Build task was available that correctly found MSBuild v15.0 and allowed me to use the new C# features. Finally!

Monday, January 22, 2018

TFS Build Server: Error CS5001: Program does not contain a static 'Main' method suitable for an entry point

When trying to build a newly created project on our build server, it failed with the following error message:

##[error]CSC(0,0): Error CS5001: Program does not contain a static 'Main' method suitable for an entry point

I was using the new async main functionality in C# 7.1 but for a reason I didn’t understand the build server didn’t pick this up. Locally however, everything was working as expected.

The only difference I noticed that I was building on my machine with a Debug configuration whereas on the Build server a Release configuration was used. And indeed after changing my local settings to Release, my build started to fail.

image

Lesson learned: You have to change the Language Version for every configuration you are using…

Friday, January 19, 2018

MassTransit–No queue is created

Yesterday, I was working on a new project where we planned to use MassTransit. After creating the RabbitMQ configuration and publishing a first message, I noticed that an Exchange was created in RabbitMQ but that it was not bound to a queue. This resulted in the fact that the message was lost Sad smile.

Here is the related code:

In the RabbitMQ administration I saw the following in the list of Exchanges:

image

But when I clicked on the Exchange to view the details, I saw that the exchange was not linked to any queue:

image

As I found out, this is expected behavior in MassTransit.

From StackOverflow:

Publishing a message does not create any queues. Queues are created when receive endpoints are added to a bus. Until the receive endpoints are started, and their topology configured in RabbitMQ (the exchange-exchange-queue bindings), any messages published are not delivered because there are no bindings to any queues. Once the receive endpoints are started, those bindings exist and messages will be delivered to the queues.

Thursday, January 18, 2018

Entity Framework Core: Log parameter values

Entity Framework Core provides a rich logging mechanism that allows you to see what’s going on behind the scenes. If you register EF Core in your ASP.NET Core application using the AddDbContext method, it will integrate automatically with the logging mechanism of ASP.NET Core.

Otherwise you have a little bit extra work and should register a LoggerFactory yourself(more information here: https://docs.microsoft.com/en-us/ef/core/miscellaneous/logging)

Unfortunately after enabling it, I still couldn’t see the query parameters that were used by the EF queries. This is a security feature that is enabled by default. As query parameters can contain sensitive information, it is excluded by default from the log messages. To include this information you have to explicitly enable it by calling EnableSensitiveDataLogging():

From the documentation

Enables application data to be included in exception messages, logging, etc. This can include the values assigned to properties of your entity instances, parameter values for commands being sent to the database, and other such data. You should only enable this flag if you have the appropriate security measures in place based on the sensitivity of this data.

You have to add this code to the OnConfiguring method of your DbContext:

Wednesday, January 17, 2018

ElasticSearch debugging–Log request and response messages using NEST

It can sometimes be quiet hard to figure out why a specific ElasticSearch query fails or don’t returns the expected results. As I’m using NEST, the high-level ElasticSearch client, it is not always obvious what is exactly happening behind the scenes.

Here is a code snippet that allows you to log the generated request and response messages:

Remark: Using this code has a performance impact, so only use it for development or testing purposes.

Tuesday, January 16, 2018

Debugging a .NET Core project in VS 2017 - Unable to start program, An operation is not legal in the current state

When trying to debug a .NET Core application using Visual Studio 2017, attaching the debugger suddenly started to fail with the following error message:

Unable to start program, An operation is not legal in the current state

Starting without a debugger attached worked, but attaching the debugger later on didn’t. Rebuilding my project, restarting Visual Studio, restarting my PC, all seemed to not bring a solution to the table.

This is a known issue, the solution (workaround) is to turn off JavaScript debugging on Chrome:

  • Go to Tools –> Options –> Debugging –> General
  • Turn off the setting for Enable JavaScript Debugging for ASP.NET (Chrome and IE)

image

Remark: A fix will be provided in the Visual Studio 2017 15.6 release.

Monday, January 15, 2018

StructureMap: Using the IoC container inside the Registry

StructureMap has an easy to use Registry DSL that can be used in a Registry class. By using (one or more) Registry classes you can group all your IoC plumbing together.

Yesterday I had a situation where I wanted to use some object that was already registered in the IoC container in the registration of another class. This is possible by passing an IContext as a second parameter of the Use() method in the fluent API: