ASP.NET Core 1.x – curios case of missing IOptions<T> array item

1. Introduction

Last week while I was working on one of the features for my current project, I noticed quite surprising behavior of IOptions<T> object. Long story short, for some reasons there were missing array elements in my parsed application settings class.

2. Problem

Just like everyone else, we store our application settings in JSON file. The settings are pretty straightforward, just a bunch of properties with some nested objects

which are bound to the AppSetting class thanks to these couple of lines of code

where AppSettings class looks as follows

As you can see nothing too fancy in here, standard ASP.NET Core approach for handling configuration files. However, if you access the PaymentMethods property of IOptions<AppSettings>

you will see that instead of four elements we ended up having 3 items

as the “Visa” element is missing.

3. Solution

If you look closely at the appsettings.json file you will notice that a “Visa” item configuration is a bit different than the ones which are parsed just fine. Namely null is assigned to excludedCurrencies property, whereas in other items an empty array or no property at all is used. So the first fix is just to use the same approach as in the other items

This approach works fine, however, it is not a silver bullet as someone still might use null and introduce a bug. Another fix might be upgrading to ASP.NET Core 2.0 as the problem doesn’t seem to exist in there. Of course, this is rather a huge change so not everyone will be willing to do it. The last option is a manual installation of Microsoft.Extensions.Configuration.Binder 2.0 along with Microsoft.Extensions.Configuration.Json 2.0 package. However, this approach requires you to retarget your application to netcoreapp2.0. One way or another every solution in here works fine, so once you apply the fix you will see all items in the array
Source code for this post can be found here

ASP.NET Core 1.x – curios case of missing IOptions<T> array item

.NET Core – calculating code coverage with OpenCover (on Windows)

1. Introduction.

I’ve been struggling for some time to make OpenCover work with .NET Core projects, so I’ve decided to document a working example. This is basically an aggregation of hints and answers I found on the Web (especially in here)

2. Working example.

If you run an OpenCover with the same arguments you were running it for a classic framework, you will end up with something like this
As you can see the coverage was not calculated and OpenCover is complaining about a missing PDBs. In order to fix that we have to do two things. First of all, we have to build the project with a full PDBs

And then run OpenCover with and -oldStyle switch

From now on, OpenCover recognizes PDB files and the code coverage is calculated correctly

3. Cake script.

As we use a Cake as our build automation tool I’ve also prepared a sample script for generating a code coverage. The core part of the script looks as follows

Notice that script is able to merge code coverage results from multiple test projects thanks to MergeOutput flag passed to OpenCover.


Full sources of that script (along with a dotnet vstest alternative approach) can be found here.

.NET Core – calculating code coverage with OpenCover (on Windows)

ASP.NET Core – request serialization issues after migration from classic WebApi

We’ve been migrating a classic WebApi application into the ASP.NET Core API for quite a while now, and last week we decided to deploy it on the test environment and try to run a website against it. We were pretty confident about the quality of a migration because all of the integration tests from old API were green when running against a new one. We were expecting maybe some business logic bugs but from our perspective, the infrastructure part was good to go. Unfortunately, when the QA’s run the selenium test suite they quickly found a major issue in our codebase. They basically were getting HTTP 500 errors indicating a NullReferenceException. That was pretty surprising to us and after a bit of a digging we found following lines in the logs

this was resulting in a null request in controller’s action
As you can see JSON serializer was not able to convert null into the int. We double checked the requests coming from front-end and this is how one of them looked like

whereas corresponding request class on the server side was written in following way

Clearly front-end shouldn’t be sending a null as a PassengerNumber however the same request was serialized just fine when running against classic WebApi
Fortunately the fix for that was pretty straightforward. All we had to do was to configure JSON serializer to ignore null values.

From now on we were able to properly serialize the request
Source code for this post can be found here

ASP.NET Core – request serialization issues after migration from classic WebApi

NLog.Web.AspNetCore – make sure you add error message for logging exception

I’ve been using NLog for quite some time already, and it was a natural choice to use it in the ASP.NET Core projects as well. I’ve configured the logger using this tutorial and everything seemed to be working fine. Unfortunately, after some time we’ve noticed that for some reasons some of the errors are not logged. We’ve taken a deeper look at our code base and we’ve found couple logs being written as follows

This piece of code works perfectly fine with ASP.NET Core console logger but it seems it doesn’t for NLog.
We double checked that with following piece of code

And as you can see in the picture below, no errors have been reported

Changing the error message to any message (even the one containing only white spaces)

fixed the problem.

That looks like a bug for me, so I will create a PR with the fix and see if that will make its way to the “master”

As usual, the source code for this post can be found on my GitHub

NLog.Web.AspNetCore – make sure you add error message for logging exception

XUnit – MemberDataAttribute and generic type inheritance

1. Introduction.

When I was writing Cake.Intellisense I was playing a lot with Roslyn syntax rewriters. The one thing which was pretty important for me at this time was a reliable set of tests which can quickly show if rewritten code is valid C# code and if it matches my expectations. As I don’t like to repeat my code I wanted to have a base test class which can be provided with different test cases from inherited classes. The initial implementation looked as follows

As you can see I have a generic base test class which holds test cases in a static field TestCases. The field is static as it is required by XUnit, this solution is perfectly valid because a static field is shared across all instances of the same type. Having a base test class ready I wanted to write a set of unit tests for following syntax rewriter

The rewriter shown above is a very simple piece of code which replaces internal class modifier with a public one. Writing the tests for that class was supposed to be very easy, I just had to provide test cases with input code and expected result.

Unfortunately running the tests resulted in InvalidOperationException being thrown from XUnit

If you look closely at the message you will notice that the TestCases field used for providing data was not initialized, which means that the static constructor of class InternalToPublicClassModifierSyntaxRewriterTests was not run. That was pretty surprising for me that is why I wanted to investigated the issue a bit more.

2. Investigation.

I started from going back to the basics. As we probably all know, the static constructor is triggered when one of the following events occur:

  • An instance of the class type is created.
  • Any of the static members of the class type are referenced

The first condition is not met because instance of the test class is created after test cases are enumerated. That is why member data fields have to be a static fields/properties etc. When it comes to second condition the situation in here is a bit more complicated but if you take a look at the MemberDataAttributeBase class

you will notice that member data looks for properties in DeclaringType of method. In my case declaring type is

not

So when XUnit accesses TestCase property the static constructor from InternalToPublicClassModifierSyntaxRewriterTests class will not be called either as the types does not match.

3. Solution.

In order to bend the behavior of XUnit to my needs, I had to ensure that the static constructor from inherited class is called. Fortunately, workaround is pretty straightforward – I had to introduce a custom MemberDataAttribute which calls static constructor from ReflectedType manually

Now all I have to do is use newly created attribute in CSharpSyntaxRewriterTest test class

From now on all of the test cases will be run correctly

Source code for this post can be found here

XUnit – MemberDataAttribute and generic type inheritance