1

I am using Refit to define my HttpProxy method. I also got a custom Delegating handling a bearer token request that it inserts before the request is being sent through.

In order to generate a token, I need an ID. I am sending this ID by using headers:

Task<Response> UserInfo (string id, [Header("identity")] string identity);

The first Id is a query string and identity, header, are the same value. Thus during a call it looks very ugly:

UserInfo("234","234");

(No I don't want to read from query string as the handler is generic)

And my handler looks like this, where first I read from the header and then remove the same from the header:

if (request.Headers.TryGetValues("identity", out IEnumerable<string> values))
            {
                var immutableIdentity = values.ToImmutableArray();
                if (!immutableIdentity.IsNullOrEmpty())
                {
                    var identity = immutableIdentity.First();
                    request.Headers.Remove("identity");
                    return GenerateToken(identity);
                }
            }

Rather than using a header to communicate between a Refit proxy and HttpDelegete, what is the next possible option do I have?

codebased
  • 6,945
  • 9
  • 50
  • 84

1 Answers1

1

I think you can use the Property attribute instead of Header attribute. This section is taken from the Refit Documentation:

If there is runtime state that you need to pass to a DelegatingHandler you can add a property with a dynamic value to the underlying HttpRequestMessage.Properties by applying a Property attribute to a parameter:

public interface IGitHubApi
{
    [Post("/users/new")]
    Task CreateUser([Body] User user, [Property("SomeKey")] string someValue);

    [Post("/users/new")]
    Task CreateUser([Body] User user, [Property] string someOtherKey);
}

Then you can access these variables like this:

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

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // See if the request has a the property
        if(request.Properties.ContainsKey("SomeKey"))
        {
            var someProperty = request.Properties["SomeKey"];
            //do stuff
        }

        if(request.Properties.ContainsKey("someOtherKey"))
        {
            var someOtherProperty = request.Properties["someOtherKey"];
            //do stuff
        }

        return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
    }
}

Also, you need to consider this additional warning:

Note: in .NET 5 HttpRequestMessage.Properties has been marked Obsolete and Refit will instead populate the value into the new HttpRequestMessage.Options.

Mustafa Sadedil
  • 180
  • 2
  • 11