Configure HttpClientFactory to Use Fiddler in .NET Core Microservices-based Docker Containers
Tags: microservices, fiddler, docker, dotnetcore
Published: 2019-06-15 16:12:36

---
title: Configure HttpClientFactory to Use Fiddler in .NET Core Microservices-based Docker Containers
published: true
tags: microservices,fiddler,docker,dotnetcore
canonical_url: https://medium.com/@joni2nja/configure-httpclientfactory-to-use-fiddler-in-net-core-microservices-based-docker-containers-2540bd87c14
---

This post originally appeared on [Medium](https://medium.com/@joni2nja/configure-httpclientfactory-to-use-fiddler-in-net-core-microservices-based-docker-containers-2540bd87c14)

Ever wonder how to configure your Dockerized applications to use Fiddler?

![](https://cdn-images-1.medium.com/max/1024/1*RrzfRcoC2Uh6Igm4S4eKnw.png)

If all of the following conditions are true, then this post might help you. Hopefully.

- You are developing microservices-based applications using [.NET Core](https://dot.net) 2.1 or above
- You develop using [Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/) (minimum version: 18.03)
- You are using [HttpClientFactory](https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests#what-is-httpclientfactory), an opinionated factory for creating HttpClient instances
- You love [Fiddler](https://www.telerik.com/fiddler) and trying to configure your HttpClient to use Fiddler as the debugging proxy

Let’s say our Docker container application has the following `HttpClientFactory` setup in `Startup.cs`:

```cs
services.AddHttpClient("mySuperSplendidMarvelousAmazingService")
  .SetHandlerLifetime(TimeSpan.FromMinutes(5))
  .AddPolicyHandler(GetRetryPolicy())
  .AddPolicyHandler(GetCircuitBreakerPolicy());
```

Note that `AddPolicyHandler(...)` might be a typical Microservices pattern you can possibly use. See “[.NET Microservices: Architecture for Containerized .NET Applications](https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly)” references.

Now, to configure the `HttpClient` to “talk” to the Fiddler on the host port 8888 ([Fiddler listens on port 8888 by default](https://docs.telerik.com/fiddler/configure-fiddler/tasks/UseFiddlerAsReverseProxy)), we will need to know the host IP address. Thanks to Docker v18.03, we can use the special DNS name `host.docker.internal`.

Refer to the documentation for more details:

[Networking features in Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/networking/)

So let’s use that special DNS:

```cs
services.AddHttpClient("mySuperSplendidMarvelousAmazingService")
  .SetHandlerLifetime(TimeSpan.FromMinutes(5))
// ADD THIS 👇👇👇
  .ConfigurePrimaryHttpMessageHandler(() =>  
  {  
      return new HttpClientHandler  
      {  
          Proxy = new WebProxy("http://host.docker.internal:8888"),  
          UseProxy = true  
      };  
  }) 
// --------- 👆👆👆
  .AddPolicyHandler(GetRetryPolicy())
  .AddPolicyHandler(GetCircuitBreakerPolicy());
```

That’s it! Now we should be able to inspect the requests/responses in Fiddler.

But wait 🛑⛔🚫!! We don’t want to ship that debugging code to the production, right? Of course not. But sometimes we just want to be able to use it during debugging with a simple flip. Let’s explore some possible solutions:

- Use Preprocessor Directive
- Use ConditionalAttribute

### Use Preprocessor Directive

We accomplish this by using a C# [_preprocessor directive_](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-if):

```cs
services.AddHttpClient("mySuperSplendidMarvelousAmazingService")
  .SetHandlerLifetime(TimeSpan.FromMinutes(5))
#if DEBUG 😎
  .ConfigurePrimaryHttpMessageHandler(() =>
  {
      return new HttpClientHandler
      {
          Proxy = new WebProxy("http://host.docker.internal:8888"),
          UseProxy = true
      };
  })
#endif
  .AddPolicyHandler(GetRetryPolicy())
  .AddPolicyHandler(GetCircuitBreakerPolicy());
```

This way, on the production build, it won’t be compiled into Microsoft Intermediate Language (MSIL, or IL for short).

Looks good. Until it’s not. It will fail if we forget to launch Fiddler every time we start our application in the debug mode. So, a better alternative, define and use our own custom symbol, for example: `ENABLE_FIDDLER_DEBUG_PROXY`:

```cs
services.AddHttpClient("mySuperSplendidMarvelousAmazingService")
  .SetHandlerLifetime(TimeSpan.FromMinutes(5))
#if ENABLE_FIDDLER_DEBUG_PROXY 😍
  .ConfigurePrimaryHttpMessageHandler(() =>
  {
      return new HttpClientHandler
      {
          Proxy = new WebProxy("http://host.docker.internal:8888"),
          UseProxy = true
      };
  })
#endif
  .AddPolicyHandler(GetRetryPolicy())
  .AddPolicyHandler(GetCircuitBreakerPolicy());
```

And define it only when we really need it:

![](https://cdn-images-1.medium.com/max/660/1*AgESqiTbEb_KXnLoWdvzZA.png)

Awesome! 👍

### Use ConditionalAttribute

Another possible solution, make use of [ConditionalAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.conditionalattribute). Let’s add an extension method:

```cs
public static class FiddlerExtensions
{
[Conditional("ENABLE_FIDDLER_DEBUG_PROXY")]
  public static void AddFiddler(this IHttpClientBuilder builder)
  {
    builder.ConfigurePrimaryHttpMessageHandler(() =>
    {
      return new HttpClientHandler
      {
        Proxy = new WebProxy("http://host.docker.internal:8888"),
        UseProxy = true
      };
    });
  }
}
```

and use it like:

```cs
var builder = services.AddHttpClient("mySuperSplendidMarvelousAmazingService")
  .SetHandlerLifetime(TimeSpan.FromMinutes(5))
  .AddPolicyHandler(GetRetryPolicy())
  .AddPolicyHandler(GetCircuitBreakerPolicy());
builder.AddFiddler();
```

The beauty of this is, the `builder.AddFidler()` won’t be included in the IL if we don’t have `ENABLE_FIDDLER_DEBUG_PROXY` defined.

Now, the ugly part, we can’t continue chaining the method calls because it will end up being removed from the IL altogether, thus we are introducing a variable `builder` here. You can use [ILSpy](https://github.com/icsharpcode/ILSpy) or [dnSpy](https://github.com/0xd4d/dnSpy) to disassemble and verify this behavior.

**Bonus tips!**

There is another cool trick for debugging: [Debugger.IsAttached](https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.debugger.isattached)

> Gets a value that indicates whether a debugger is attached to the process.

```cs
if (Debugger.IsAttached) { ... }
```

This might be useful for some certain scenarios, but I don’t think I will use it for this scenario.

What’s your solution?