DelegatingHandler not working using Refit in a .NET MAUI App

240 Views Asked by At

I have this DelegatingHandler (see final part of this post) that i use in all my mobile apps, this allows me to see in Output Window of my IDE all the Network stuff, very neat. Feel free to use it

Now, normally, ill use it as this:

httpClient = new HttpClient(new HttpLoggingHandler())
            {
                BaseAddress = new Uri("myUri"),
                Timeout = TimeSpan.FromSeconds(5)
            };

And it has always worked.

Now i am trying to use HttpFactory Pattern with Refit in a New App

builder.Services.AddRefitClient<ILoginService>()
            .ConfigureHttpClient(c => c.BaseAddress = new Uri("myUri"))
            .AddHttpMessageHandler<HttpLoggingHandler>();
        return builder;

And this doesnt work. I get an Exception and MainPage cant be resolved

If i comment the .AddHttpMessageHandler part, it works.

What i am doing wrong? Any help would be appreciated

 public class HttpLoggingHandler : DelegatingHandler
    {
        public HttpLoggingHandler(HttpMessageHandler? innerHandler = null)
            : base(innerHandler ?? new HttpClientHandler())
        {
        }

        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var req = request;
            string id = Guid.NewGuid().ToString();
            string msg = $"[{id} -   Request]";


            Debug.WriteLine($"{msg}========Start==========");
            Debug.WriteLine($"{msg} {req.Method} {req.RequestUri.PathAndQuery} {req.RequestUri.Scheme}/{req.Version}");
            Debug.WriteLine($"{msg} Host: {req.RequestUri.Scheme}://{req.RequestUri.Host}");

            foreach (var header in req.Headers)
            {
                Debug.WriteLine($"{msg} {header.Key}: {string.Join(", ", header.Value)}");
            }

            if (req.Content != null)
            {
                foreach (var header in req.Content.Headers)
                {
                    Debug.WriteLine($"{msg} {header.Key}: {string.Join(", ", header.Value)}");
                }

                if (req.Content is StringContent
                    || IsTextBasedContentType(req.Headers)
                    || IsTextBasedContentType(req.Content.Headers))
                {
                    string result = await req.Content.ReadAsStringAsync();

                    Debug.WriteLine($"{msg} Content:");
                    Debug.WriteLine($"{msg} {result}");
                }
            }

            var start = DateTime.Now;

            var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);

            var end = DateTime.Now;

            Debug.WriteLine($"{msg} Duration: {end - start}");
            Debug.WriteLine($"{msg}==========End==========");

            msg = $"[{id} - Response]";
            Debug.WriteLine($"{msg}=========Start=========");

            var resp = response;

            Debug.WriteLine(
                $"{msg} {req.RequestUri.Scheme.ToUpper()}/{resp.Version} {(int)resp.StatusCode} {resp.ReasonPhrase}");

            foreach (var header in resp.Headers)
            {
                Debug.WriteLine($"{msg} {header.Key}: {string.Join(", ", header.Value)}");
            }

            if (resp.Content != null)
            {
                foreach (var header in resp.Content.Headers)
                {
                    Debug.WriteLine($"{msg} {header.Key}: {string.Join(", ", header.Value)}");
                }

                if (resp.Content is StringContent
                    || IsTextBasedContentType(resp.Headers)
                    || IsTextBasedContentType(resp.Content.Headers))
                {
                    start = DateTime.Now;
                    string result = await resp.Content.ReadAsStringAsync();
                    end = DateTime.Now;

                    Debug.WriteLine($"{msg} Content:");
                    Debug.WriteLine($"{msg} {result}");
                    Debug.WriteLine($"{msg} Duration: {end - start}");
                }
            }

            Debug.WriteLine($"{msg}==========End==========");
            return response;
        }

        private readonly string[] types = { "html", "text", "xml", "json", "txt", "x-www-form-urlencoded" };

        private bool IsTextBasedContentType(HttpHeaders headers)
        {
            IEnumerable<string> values;
            if (!headers.TryGetValues("Content-Type", out values))
            {
                return false;
            }

            string header = string.Join(" ", values).ToLowerInvariant();

            return types.Any(t => header.Contains(t));
        }
    }

I am Stuck, any help will be appreciated

1

There are 1 best solutions below

0
On

Found a Solution! Here How do I log HTTP requests when using Refit in .net core?

Removing constructor from your custom handler should do it. The current implementation of the handler always initialise itself with the parameterised constructor, which makes InnerHandler not null.

Now everything works!