-1

So I have some code from a previous working project. but for some reason when I use the relevant code in my new project it refuses to work. Essentially I am trying to make a call out to an api and receive their token. I have to pass in the body of the request a grant_type and then my username and password. Now everything works fine up until I hit the line client.PostAsync();

Then the debugger just kinda stops?(no exceptions or errors). I mean it continues to run but it never hits the next line.

I have tried .ConfigureAwait(false) still nothing. I have tried await client.PostAsync(). I've tried just about everything I can find here on StackOverflow. I am not sure what I'm missing but then again thats why I'm making this post. Maybe theres something different between the projects but I checked the references and they all seem to match.

Additional context: The code that is executing is a restful api (not a console application). So its an api reaching out to another api to receive a token and then either make more calls with the aforementioned token and/or then do some business logic with.

Edit: Just remembered something. In post man I can make the call correctly and I get the result so the destination is working.

here is the relevant code:

private HttpClient HttpClientSetup()
{
    var client = new HttpClient(new LoggingHandler(new HttpClientHandler())) { BaseAddress = new Uri(_apiBaseUrl), Timeout = TimeSpan.FromMilliseconds(45000) };
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    return client;
}    
private myObj GetToken()
{
    HttpClient client = HttpClientSetup();
    var form = new Dictionary<string, string>
    {
       {"grant_type", "client_credentials"},
       {"client_id", _username},
       {"client_secret", _password},
    };
    try
    {
        HttpResponseMessage response = client.PostAsync("auth/token", new FormUrlEncodedContent(form)).Result;
        //more stuff
    }
    catch(Exception e)
    {
        //stuff
    }
}
jtslugmaster08
  • 182
  • 1
  • 16
  • 3
    *Don't* block asynchronous calls. For all anyone knows you just blocked the UI and caused a deadlock. This is simply bad code. Using `.Configureawait(false) ` won't prevent blocking when you explicitly call `.Result` and block. The only reason it worked until now was luck – Panagiotis Kanavos Aug 25 '21 at 14:47
  • see a more complete example at : https://stackoverflow.com/questions/38494279/how-do-i-get-an-oauth-2-0-authentication-token-in-c-sharp/53787718#53787718 – granadaCoder Aug 25 '21 at 15:01
  • @granadaCoder thats what I started with. got it working in a different project but my new project doesnt want to return with a result. – jtslugmaster08 Aug 25 '21 at 15:05

4 Answers4

2

When you use asynchronous methods like PostAsync, you'll want to await those to get the result of the asynchronous Task.

Relevant changes include making your method async and to return a Task of the result type:

private async Task<myObj> GetToken(){
...

Then await-ing the call:

HttpResponseMessage response = await client.PostAsync(...

For background, consult the docs for async programming.

Noah Stahl
  • 6,905
  • 5
  • 25
  • 36
  • Same result. the debugger just kinda stops. – jtslugmaster08 Aug 25 '21 at 14:53
  • 2
    @PanagiotisKanavos Why would anyone upvote an answer suggesting a solution the question specifically states they've already tried and didn't solve the problem? – Servy Aug 25 '21 at 14:54
  • 1
    @jtslugmaster08 it would stop if you were trying to connect to your own identity service which, at this point, would be stopped by the debugger. Does the server respond in the first place? – Panagiotis Kanavos Aug 25 '21 at 14:54
  • @jtslugmaster08 use Fiddler or another debugging proxy to see what's actually sent and received. If the server doesn't respond, there's little you can do except handle the timeout. If you have access to the service, is it working? Has it logged anything? – Panagiotis Kanavos Aug 25 '21 at 14:56
  • Result will force task to complete and return , so adapting async await is irrelevant – Sameh Aug 25 '21 at 14:58
  • @PanagiotisKanavos I will look into the identity service but reaching out to my db works. Unfortunelty its not my server so I cant check. What I do know is that in postman I can make the call successfully and get a result back. – jtslugmaster08 Aug 25 '21 at 15:00
  • Postman doesn't show you what your HTTP requests did. Use Fiddler to see what's actually going on. Does the server respond? – Panagiotis Kanavos Aug 25 '21 at 15:04
  • @PanagiotisKanavos so fiddler either isnt seeing anything going out to the server. Or I am not using fiddler correctly. fiddler does however correctly see my call to my endpoint but no subsequent call out to the "auth/token" endpoint – jtslugmaster08 Aug 25 '21 at 15:23
  • 1
    @Noah Stahl Unfortunately this is not the answer. Yes I have already tried this along with many other solutions mentioned on the site. But your changes result in the same odd behavior. – jtslugmaster08 Aug 25 '21 at 15:36
  • @PanagiotisKanavos So the endpoint is returning a 200 response in fiddler but VS never continues debugging. – jtslugmaster08 Aug 25 '21 at 16:05
1

So I have a working solution. None of what people have been focusing on is correct. People have jumped to quickly to focus on await or async etc. Which normally may have been the case but in my question I explicitly said I had tried everything.Even after I implemented the changes Noah Satel mentioned I still had the same issue. I do appreciate Noah's response and it might help others but it was not the solution to my problem.

The solution had to do with the formatting of my request to the api.

First I learned that postman can generate code. On the right hand side there is a '</>' clicking on that and selecting in the drop down C#-RestSharp Postman provided me with this.

Using this I was able to receive a response and continue debugging. Of course I am going to try and get a working sample that doesn't use restsharp but until then this is what I am going to use.

For full context here is my token method.

using System.Text;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Newtonsoft.Json;
   using RestSharp;//If you dont have this install by going to Manage NuGet //Packages. select Browse and search RestSharp install and you should be good to go
private async Task<Token> GetToken(){
//the postman code block
var client = new RestClient("myUrl");
                client.Timeout = -1;
                var request = new RestRequest(Method.POST);
                request.AddHeader("Accept", "application/json");
                request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
                request.AddParameter("grant_type", "client_credentials");
                request.AddParameter("client_id", _username);
                request.AddParameter("client_secret", _password);
                IRestResponse response = client.Execute(request); 
//
Token newtoken = JsonConvert.DeserializeObject<Token>(response.Content);
return newtoken;
}
jtslugmaster08
  • 182
  • 1
  • 16
  • I am pretty sure i have explained the exact problem in my response but the thread owner doesn't seem to understand ! – Sameh Oct 12 '21 at 03:54
0

You can give this code snippet a try, it is for submitting json data to a post API method

        var uri = new Uri("Place uri");
        var payload = "{\"CustomerId\": 5,\"CustomerName\": \"John\"}";
        var content = new StringContent(payload, Encoding.UTF8, "application/json"); 
        var response = string.Empty;
        using (var client = new HttpClient())
        {
            HttpRequestMessage request = new HttpRequestMessage
            {
                Method = HttpMethod.Post,
                RequestUri = uri,
                Content = content
            };

            var result = await client.SendAsync(request);
            if (result.IsSuccessStatusCode)
            {
                response = result.StatusCode.ToString();
            }
        }
        return response;

Another snippet to submit form data

using (var httpClient = new HttpClient())
{
    using (var content = new FormUrlEncodedContent(postData))
    {
        content.Headers.Clear();
        content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

        HttpResponseMessage response = await httpClient.PostAsync(url, content);

        return await response.Content.ReadAsAsync<TResult>();
    }
}
Sameh
  • 1,318
  • 11
  • 11
  • 3
    Which part of this is supposed to answer the question? There's nothing wrong with `PostAsync` – Panagiotis Kanavos Aug 25 '21 at 14:53
  • 1
    What was the problem and how does this correct the problem? Why were so many changes made to the code here? – David Aug 25 '21 at 14:54
  • 1
    You are attempting to post form data, in order to do so you have to set the right content type which is "application/x-www-form-urlencoded"; I just gave you another approach to submit it as a json – Sameh Aug 25 '21 at 14:55
  • 1
    I have just clarified what's missing in your code, and added a snippet code to submit form data, What's the reason for the -ve reason, I am just trying to help! – Sameh Aug 25 '21 at 15:05
0

To see result of postAsync method in debug execute 2 steps. Screenshot: PostAsync debug

  1. return HttpResponseMessage from method with postAsync:

        private static async Task<HttpResponseMessage> methodWithPostAsync(){
        ...
        response = await client.PostAsync(url, data);
        return response
        }
    
  2. call method and wait for response message status:

    Task<HttpResponseMessage> content= methodWithPostAsync();
    while (!content.IsCompleted)
    {
        Console.WriteLine("busy");
        System.Threading.Thread.Sleep(1000);
    }
    
smirad91
  • 19
  • 1
  • 4