DNX and ASP.NET Core support for Raygun4Net

| 5 min. (951 words)

Microsoft’s new .NET Execution Environment (DNX) is in Release Candidate, and now has enough of the features we need to provide a useful Raygun client. The new APIs are quite different from the old so we’ve had to rewrite a bit of the library, but it’s useable now. In this blog post I’ll run through how to use it with ASP.NET Core RC1, what we needed to change to get it to work with DNX, and what is still missing due to lack of framework support.

If you’re looking for the code itself, it’s sitting in a pull request here: https://github.com/MindscapeHQ/raygun4net/pull/292 and can be downloaded from Nuget here: https://www.nuget.org/packages/Mindscape.Raygun4Net.AspNetCore/0.1.0-beta1. Please add any comments or bugs you have to the Pull Request.

Using the new ASP.NET Core Client

Using the new ASP.NET Core Raygun client is pretty easy.

  1. In your project.json file, add “Mindscape.Raygun4Net.AspNetCore”: “0.1.0-beta1”
to your dependencies.
  1. Run dnu restore or restore packages within Visual Studio to download the package.

  2. Add this to your appsettings.json (if you’re using another type of config, add it there)

    "RaygunSettings": {
      "ApiKey": "{PUT YOUR OWN API KEY HERE}"

  3. In Startup.cs:

    1. Add using Mindscape.Raygun4Net.AspNetCore; to your using statements.
    2. Add app.UseRaygun(); to the top of the Configure method.
    3. Add services.AddRaygun(Configuration); to the ConfigureServices method.

That’s it! This adds the RaygunAspNetCoreMiddleware to the top of your middleware stack, which means it will be the first thing to handle requests as they come in, but more importantly the last to handle the Response on the way out. This means that it can see the final Response of any exceptions that have been triggered.

There’s also few extra configuration options you’ll probably want to look at.

The AddRaygun method has an overload that takes a RaygunMiddlewareSettings object. These settings control the middleware (RaygunSettings are the common settings we use across all of our providers). Currently there’s just one property on it, ClientProvider. This gives you a hook into the loading of RaygunSettings and the construction of the RaygunAspNetCoreClient used to send errors.

For example, say you want to set user details on your error reports. You’d create a custom client provider like this:

public class ExampleRaygunAspNetCoreClientProvider : DefaultRaygunAspNetCoreClientProvider
    public override RaygunAspNetCoreClient GetClient(RaygunSettings settings)
      var client = base.GetClient(settings);
      client.UserInfo = new RaygunIdentifierMessage("123456789")
        Email = "test@example.com",
        FullName = "Jamie"
      return client;

Then you would change your AddRaygun() call in ConfigureServices to this:

services.AddRaygun(Configuration, new RaygunMiddlewareSettings()
  ClientProvider = new ExampleRaygunAspNetCoreClientProvider()

IRaygunAspNetCoreClientProvider also has a GetRaygunSettings method you can implement which takes the settings loaded from your configuration file and lets you change them in code.

Changes in .NET Core

There were a few issues with compiling our existing provider under the dnxcore50 framework when we first looked at ASP.NET Core (then ASP.NET 5).

First up: we use a compiled in version of SimpleJson to serialize the exception payload before we send it to Raygun. This uses reflection to get the properties it should be serializing, but the reflection API has changed in .NET Core to match the way it works in Windows Store / Phone / PCL. This means using Type.GetTypeInfo() instead of accessing reflected information directly on the Type class. Thankfully, SimpleJson already has a compile time flag to call GetTypeInfo() instead of getting the Type directly, so it was just a case of defining that flag to get it to work.

The APIs around HttpContext, Request, and Response have changed:

  • Request doesn’t have a Url property on it any more, but it has all the parsed details so you can rebuild it using the GetDisplayUrl() extension method.
  • The client connection properties have been moved off the Request object into their own ConnectionInfo class – this object can be found on the HttpContext.
  • Form values aren’t automatically parsed, you need to check if the Request has the correct Content-Type, then call ReadFormAsync() to read and parse them.
  • We can’t get ServerVariables any more, there doesn’t seem to be an API for them.
  • Getting the Response’s reason phrase is a bit strange, it’s not exposed on the Response object itself so you need to get it from httpContext.Features.Get()?.ReasonPhrase.
  • There doesn’t seem to be a built in way to determine if the Connection is Local or not (the IsLocal property on ConnectionInfo has been removed from the latest version as it is never set), so we had to remove the ExcludeErrorsFromLocal setting for now.

In other versions of the Client, we set the Version property automatically if we find one on your Assembly (using Assembly.GetEntryAssembly().GetName().Version.ToString()). Unfortunately GetEntryAssembly() is gone, so we can’t do that any more. You’ll need to set the ApplicationVersion property in either your RaygunSettings config, or on the RaygunAspNetCoreClient itself.

Most of the Send methods on RaygunAspNetCoreClient are async now, as quite a few of the underlying framework methods are async.

We were using WebClient to send the error payload to the Raygun API, but that is not in the new framework so we’ve replaced it with HttpClient. Not too much needed to change here, although we lost Proxy support. I tried to use the HttpClientHandler method of setting the proxy, but didn’t have much luck.

Missing Features

Lots of these were covered above, but I thought it would be easier to outline them all here so it’s easier to see at a glance.

  • [DNX Core 5.0] MachineName is not set.
  • [DNX Core 5.0] None of the Environment information is set.
  • [All] No support for setting the Proxy to use for sending errors to Raygun API.
  • [All] ExcludeErrorsFromLocal has been removed until we can find a way to determine if HTTP requests are from the local machine.
  • [All] The Version property is not automatically set from the AssemblyVersionAttribute.
  • [All] ServerVariables are missing.