0

I am new to writing generic methods in C# and I am trying to create a generic SendAsync method in my c# project. Code is given below.

HttpClientHelper.cs

public static async Task<TOut> ExecuteRequest<TIn,TOut>(TIn request, string url)
{
    Uri requestUri = new Uri(url);
    string payload = JsonConvert.SerializeObject(request);
    HttpContent httpContent = new StringContent(payload, Encoding.UTF8, "application/json");

    HttpRequestMessage requestMessage = new HttpRequestMessage
    {
        Method = HttpMethod.Post,
        RequestUri = requestUri,
        Content = httpContent
    };

    return await SendUriAsync<TOut>(requestMessage);
}

public static async Task<T> SendUriAsync<T>(HttpRequestMessage requestMessage)
{
    CancellationTokenSource source = new CancellationSource();
    CancellationToken token = source.Token;
    string client_id = "1234";
    
    using (var client = new HttpClient())
    {
        var clientCred = Encoding.UTF8.GetBytes($"{client_id}");
        client.DefaultRequestHeaders.Add("Authorization", "Basic "+Convert.ToBase64String(clientCred));
        using(var result = await client.SendAsync(requestMessage, token))
        {
            result.EnsureSuccessStatusCode();
            var response = await result.Content.ReadAsStringAsync();
            
            if(result.IsSuccessStatusCode && response != null)
            {
                return JsonConvert.DeserializeObject<T>(response);
            }
            else
            {
                throw new ApiException{ status = (int)result.StatusCode};
            }
        }        
    }
}

Here is the controller class which calls these methods:

CarSalesController.cs

string thirdpartyUrl = "someurl";
var responseObject = await HttpClientHelper.ExecuteRequest<CarObject, string>(requestObject, thirdpartyUrl);

I am getting error in the HttpClientHelper class. The error is:

ResponseStatusCode does not indicate success. StatusCode:401 - UnAuthorised

But the same API works well when I use postman. Here is the cURL

curl --location --request GET 'someurl'
--header 'client_id:1234'
--header 'Authorization: Basic asdf'
--header 'Content-Type: application/json'
--data-raw '{ "data1":"somedata1", "data2":"somedata2" }'

What could be wrong in my code?

Learner
  • 15
  • 8

2 Answers2

0

Try

request.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue(
        "Basic", Convert.ToBase64String(
            System.Text.ASCIIEncoding.ASCII.GetBytes(
               $"{client_id}")));
Roman Ryzhiy
  • 1,540
  • 8
  • 5
  • How would this help? `Encoding.ASCII` returns `ASCIIEncoding` which is the 7-bit US-ASCII range that's *identical* with the same range in UTF8. This code will replace any characters outside that range with `?`, thus mangling the value – Panagiotis Kanavos Aug 26 '20 at 12:28
  • @PanagiotisKanavos it uses AuthenticationHeaderValue instead, that is the main point. – Roman Ryzhiy Aug 26 '20 at 12:31
  • And that's why code-only answers aren't considered good answers. One would have to diff the code to find out what's changed and the most visible difference is a bug – Panagiotis Kanavos Aug 26 '20 at 12:33
0

you need to use

client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

Instead of

client.DefaultRequestHeaders.Add("Authorization", "Basic "+Convert.ToBase64String(clientCred));

For example :

static async void HTTP_GET()
        {
            var TARGETURL = "http://en.wikipedia.org/";

            HttpClientHandler handler = new HttpClientHandler()
            {
                Proxy = new WebProxy("http://127.0.0.1:8888"),
                UseProxy = true,
            };

            Console.WriteLine("GET: + " + TARGETURL);

            // ... Use HttpClient.            
            HttpClient client = new HttpClient(handler);

            var byteArray = Encoding.ASCII.GetBytes("username:password1234");
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

            HttpResponseMessage response = await client.GetAsync(TARGETURL);
            HttpContent content = response.Content;

            // ... Check Status Code                                
            Console.WriteLine("Response StatusCode: " + (int)response.StatusCode);

            // ... Read the string.
            string result = await content.ReadAsStringAsync();

            // ... Display the result.
            if (result != null &&
            result.Length >= 50)
            {
                Console.WriteLine(result.Substring(0, 50) + "...");
            }
        }
    
  • I have stored bytearray in clientCreds. var clientCred = Encoding.UTF8.GetBytes($"{client_id}"); – Learner Aug 26 '20 at 12:54