'Converting from Restclient to Httpclient in C#

I want to convert this code written with restclient to httpclient. I just don't know how best to do this!

This is my code

    public static string LoginAndGetToken(string username, string password, string domain)
    {
        var token = string.Empty;

        if (!string.IsNullOrEmpty(username) || !string.IsNullOrEmpty(password))
        {
            try
            {
                var url = $"{domain}/api/token";

                var client = new RestClient(url);

                var request = new RestRequest(Method.POST);
                request.AddHeader("cache-control", "no-cache");
                request.AddParameter("grant_type", "password");
                request.AddHeader("Content-Type", "application/json; charset=utf-8");
                request.AddParameter("username", username);
                request.AddParameter("password", password);

                var response = client.Execute(request);

                if (response.StatusCode == HttpStatusCode.OK)
                {
                    var deserial = new JsonDeserializer();
                    var result = deserial.Deserialize<Token>(response);

                    //Construct token
                    token = $"{result.token_type} {result.access_token}";

                    Settings.AccessToken = $"{result.token_type} {result.access_token}";
                }
                else
                {
                    if (response.StatusCode == HttpStatusCode.Unauthorized)
                        token = string.Empty;
                }
            }
            catch (Exception ex)
            {
                //log!
            }
        }
        return token;
    }

How can i do this?

because I don't know if this is possible to convert exactly



Solution 1:[1]

This is untested code, but based on something I use already (though I use IHttpClientFactory and not HttpClient directly)

Create an instance of TokenProviderService and use GetToken(), this handles Expiry of the token and fetches a new one if needed.


public class TokenProviderService
{
    private readonly HttpClient client;
    private Token token;
    private readonly HttpRequestMessage requestMessage;

    public TokenProviderService(string username, string password, string domain)
    {
        client = new HttpClient();

        var tokenParameters = new Dictionary<string, string>
            {
                { "grant_type", "password" },
                { "username", username },
                { "password", password }
            };
        requestMessage = new HttpRequestMessage(HttpMethod.Post, $"{domain}/api/token") { Content = new FormUrlEncodedContent(tokenParameters) };
        requestMessage.Headers.Add("cache-control", "no-cache");
        requestMessage.Headers.Add("Content-Type", "application/json; charset=utf-8");
    }
    
    public async Task<Token> GetToken()
    {
        if (token == null || token.Expiry < DateTime.UtcNow.AddMinutes(1))
        {
            token = await GetNewToken();
        }
        return token;
    }

    private async Task<Token> GetNewToken()
    {       
        var response = await client.SendAsync(requestMessage);
        response.EnsureSuccessStatusCode();

        var result = await response.Content.ReadAsStringAsync();

        var tokenResp = JsonConvert.DeserializeObject<TokenResponse>(result);
        return new Token(DateTime.Now.AddSeconds(tokenResp.Expires_In), tokenResp.Access_Token);
    }
}

public record TokenResponse(int Expires_In, string Access_Token);
public record Token(DateTime Expiry, string AccessToken);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Peter Csala