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

You are developing microservices-based applications using .NET Core 2.1 or above

You develop using Docker Desktop for Windows (minimum version: 18.03)

You are using HttpClientFactory, an opinionated factory for creating HttpClient instances

You love 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 :

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” references.

Now, to configure the HttpClient to “talk” to the Fiddler on the host port 8888 (Fiddler listens on port 8888 by default), 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:

So let’s use that special DNS:



.SetHandlerLifetime(TimeSpan.FromMinutes(5))

// ADD THIS 👇👇👇

.ConfigurePrimaryHttpMessageHandler(() =>

{

return new HttpClientHandler

{

Proxy = new WebProxy("http://host.docker.internal:8888"),

UseProxy = true

};

})

// --------- 👆👆👆

.AddPolicyHandler(GetRetryPolicy())

.AddPolicyHandler(GetCircuitBreakerPolicy()); services.AddHttpClient("mySuperSplendidMarvelousAmazingService").SetHandlerLifetime(TimeSpan.FromMinutes(5))// ADD THIS 👇👇👇// --------- 👆👆👆.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:



.SetHandlerLifetime(TimeSpan.FromMinutes(5))

#if DEBUG 😎

.ConfigurePrimaryHttpMessageHandler(() =>

{

return new HttpClientHandler

{

Proxy = new WebProxy("

UseProxy = true

};

})

#endif

.AddPolicyHandler(GetRetryPolicy())

.AddPolicyHandler(GetCircuitBreakerPolicy()); services.AddHttpClient("mySuperSplendidMarvelousAmazingService").SetHandlerLifetime(TimeSpan.FromMinutes(5)).ConfigurePrimaryHttpMessageHandler(() =>return new HttpClientHandlerProxy = new WebProxy(" http://host.docker.internal:8888 "),UseProxy = true};}).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 :



.SetHandlerLifetime(TimeSpan.FromMinutes(5))

#if ENABLE_FIDDLER_DEBUG_PROXY 😍

.ConfigurePrimaryHttpMessageHandler(() =>

{

return new HttpClientHandler

{

Proxy = new WebProxy("

UseProxy = true

};

})

#endif

.AddPolicyHandler(GetRetryPolicy())

.AddPolicyHandler(GetCircuitBreakerPolicy()); services.AddHttpClient("mySuperSplendidMarvelousAmazingService").SetHandlerLifetime(TimeSpan.FromMinutes(5)).ConfigurePrimaryHttpMessageHandler(() =>return new HttpClientHandlerProxy = new WebProxy(" http://host.docker.internal:8888 "),UseProxy = true};}).AddPolicyHandler(GetRetryPolicy()).AddPolicyHandler(GetCircuitBreakerPolicy());

And define it only when we really need it:

Awesome! 👍