ASP.NET Core – default API version with url path versioning

1. Introduction.

When you start versioning your API sometimes you want to have access to your endpoints without specifying version explicitly. Thanks to Microsoft.AspNetCore.Mvc.Versioning library this can be easily achieved with proper setup of configuration action. However, it turns out that in order to enable default API version for url path versioning, there are a couple additional steps to do.

2. Default API version without url path versioning

Let’s start with the initial setup of API versioning which will work for every type of versioning apart from url path versioning. All you have to do is to assign an ApiVersionSelector and set the AssumeDefaultVersionWhenUnspecified property to true.

Now when the user will try to access the endpoint without specifying version explicitly the ApiVersionSelector will select proper version – in this case highest available version.

3. Default Api version with URL path versioning

Running the same configuration against controllers which are versioned via url path (not query string)

will result with 404 status code, as routing is not able to match the url.
404
Fortunately, unlike the ASP.NET Web API, ASP.NET Core allows us to have multiple route attributes applied to given controller, so in order to fix the issue we just have to add

attribute to versioned controllers. From now on we can access our API without specifying version as well as with version specified.
after

4. Adding default route with convention

If you don’t want to specify default route manually for every controller, you can do it via application model convention. The interesting thing about it is the fact that apart from changing existing values of application model we can also add new items to it. This means that we can add additional SelectorModel with our default route to Selectors’ collection

Now we can get rid of [Route(“[controller]”)] attribute from our versioned controllers and just rely on convention which can be added as follows

Source code for this post can be found here

ASP.NET Core – default API version with url path versioning

Asp.NET Core – populating IOptions<T> from external data source

1. Introduction

In ASP.NET Core web.config is no longer a proper place for storing application settings. New framework introduces the concept of a json based configuration and the default file which stores the settings now is appsettings.json. Here is a quick tutorial how to use new features.

2. Reading configuration

Let’s assume that our appsettings.json file looks as follows.

Thanks to ConfigurationBuilder we can parse this config and later on materialize sections or entire file into strongly typed configuration classes. Let’s say we want to parse AvailabilitySearchOptions node to following class

We can achieve that with following steps. First of all, we need to read entire configuration

And in the next step we have to register IOptions<AvailabilitySearchOptions> in the container using services.Configure<TOptions>(IConfiguration section) method

Note Configuration.GetSection(“AvailabilitySearchOptions”) passed as argument to services.Configure method.
From now on we can access AvailabilitySearchOptions settings via IOptions<AvailabilitySearchOptions> interface, which you can easily inject into your classes.

3. Populating IOptions<T> from external data source

From time to time, reading configuration just from JSON file might not be enough and for instance you would like to add additional configuration read from some external data source. Fortunately you don’t have to resign from the IOptions<T> class as it is possible to read additional data for literally any other source thanks to IConfigureOptions<T> class. All we have to do is to create a setup class which implements IConfigureOptions<T> interface

And then registering this class in our container

From now on, when value of IOptions<AvailabilitySearchOptions> is accessed for very first time, Configure method from AvailabilitySearchOptionsSetupService will be called and you will be able to set additional values for your settings. Note that values from appsettings.json will already be there.
In addition, it is possible to have multiple implementations of IConfigureOptions<T> so if you want your setup to be split into multiple classes you are good to go.
multiple
Source code for this post can be found here

Asp.NET Core – populating IOptions<T> from external data source

ASP.NET Core – tracking flow of requests with NLog

1. Introduction

A while ago I wrote an article about using MappedDiagnosticsLogicalContext for tracking request flow in your application. As we are moving our project to ASP.NET Core, I wanted to keep that functionality in place. Unfortunately, MDLC layout renderer is not available in that framework anymore(when targeting .NET Core). Luckily, there are two other renderers which can be used as a replacement:

  • aspnet-traceidentifier
  • aspnet-item

2. Configuring NLog

Before I dig into details of layout renderers mentioned above, we have to configure ASP.NET Core to use NLog as a logger. First of all, we need to grab NLog.Web.AspNetCore NuGet package. Once the package is installed we have to manually add NLog.config to the project (the file won’t be added automatically by NuGet installer). The next step is to configure NLog with our config, then configure NLogWeb and finally register NLog in LoggingFactory. All of these steps should be done in Startup class.

The final step required for NLog to work is to register HttpContextAccessor in IoC container of your choice. If you use the build one, you can do it like that

3. Using aspnet-traceidentifier renderer

Aspnet-traceidentifier layout renderer allows you to obtain value of TraceIdentifier property from current HttpContext. TraceIdentifier is basically unique id which identifies the request. The renderer can be used as follows

From now on (without any additional configuration) every log entry logged (once HttpContext is created), will contain TraceIdentifier.

4. Using aspnet-item renderer

If for some reasons we don’t like to use TraceIdentifier as our CorrelationId, we can leverage aspnet-item renderer, which basically allows you to read data from HttpContext.Items collection. However in that case, we are responsible for providing and storing unique identifier of request in HttpContext.Items. Fortunately it is pretty straightforward to do with custom middleware.

Of course we have to also use this middleware in our application so we have to add following line

in configure method of our Startup class. Having all the pieces in place, now we can append CorrelationId read from HttpContext.Items to our log entries with following configuration

From now on, CorrelationId will be automatically added to our log entries

6. It works in multithreading scenarios

If you take a closer look at logs presented above, you will see that both of the renderers can log proper CorrelationId/TraceId regardless of the thread from which the logger was called. This is possible thanks to implementation of HttpContextAccessor which uses AsyncLocal under the hood, which allows you to persist data across threads.

Source code for this post can be found here

ASP.NET Core – tracking flow of requests with NLog