0

I studied over the Internet regarding Task Async method but cannot seem to find an approach to assign my return value in Task Async to another object. The first method is to prepare HTTP Request header and Uri.

public static async Task MainAsync()
{
    string token = await AuthHelper.AcquireToken(tenantId, clientId, clientSecret);

    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
        client.BaseAddress = new Uri("https://foo.net");
        await GetValue(client);
    }
}

The second method is to use GetAsync to call to an API to get the JSON and the two last lines I extract only value from the "Value" field in the JSON body.

public static async Task<String> GetValue(HttpClient client)
{
    string url = $"/mykey/key01";

    using (var httpResponse = await client.GetAsync(url))
    {
        httpResponse.EnsureSuccessStatusCode();
        string responsContent = await httpResponse.Content.ReadAsStringAsync();
        JObject json = JObject.Parse(responsContent);
        string value = json["value"].ToString();
        return value;
    }
}

Now I would like to use this value to assign to another object, but not sure how to do so. I managed to return the valid value. Is it possible to retrieve the value from another method or even different class?

[Updated] The main function is:

        static void Main(string[] args)
        {
            try
            {
                MainAsync().Wait();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.GetBaseException().Message);
            }
        }

Update

To be more clear. The HTTP response message is a JSON format and I can return the value from Value property in this JSON. Now how I can to reuse the value from an external method or class

EagleDev
  • 1,374
  • 1
  • 7
  • 27
  • unfortunately the body of your question is a little unclear `Now I would like to use this value to assign to another object, but not sure how to do so` – TheGeneral Feb 08 '18 at 03:31
  • My apologies if this is unclear to you. The HTTP response message is a JSON format and I can return the a value from Value property in this JSON. Now I can to reuse the value from an external method or class. @MichaelRandall – EagleDev Feb 08 '18 at 03:36

2 Answers2

1

I'm not sure exactly what you are trying to achieve. And there would be thorough debates about your architecture, you can do something like this..

Update

Because your MainAsync is static it can be called form anywhere.

You just need to modify it a bit to return your result as follows :

public static async Task<string> MainAsync()
{
    ...
    return await GetValue(client);
    ...

And somewhere else

public class MyAwesomeClass
{
    public async Task DoMagic()
    {

       var newValueOfSomething = await MainAsync();
       // hilarity ensues
    }
}
TheGeneral
  • 69,477
  • 8
  • 65
  • 107
  • Thank you for your prompt support. Followed by your suggestion, I get error "Cannot implicitly convert type 'void' to string" at this statement `return await GetValue(client);`. I updated a bit more in my question. – EagleDev Feb 08 '18 at 04:16
  • @ThuanNg make sure your you have this `public static async Task MainAsync()` take note of the `Task` – TheGeneral Feb 08 '18 at 04:19
  • Yes it was added `public static async Task MainAsync()` – EagleDev Feb 08 '18 at 04:38
0

You can Make it more generic and useful, something like below :

Your initial method can be changes to :

   public async Task<T> GetContentAsync<T>(HttpClient client)
            {
                 string url = $"/mykey/key01";

        using (var httpResponse = await client.GetAsync(url))
        {
            httpResponse.EnsureSuccessStatusCode();
            string responsContent = await httpResponse.Content.ReadAsStringAsync();
            return Deserialize<T>(json);
        }
            }

 private T Deserialize<T>(string json)
        {
            return JsonConvert.DeserializeObject<T>(json, SerializationSettings);
        }

You can now call method like :

var person = await GetContentAsync<Person>(/*http client*/)
rahulaga_dev
  • 2,985
  • 4
  • 21
  • 38
  • Thank you for your help. From `return Deserialize(json);` I understand that you need to convert json to string? What I'm getting is "json does not exist in the context". – EagleDev Feb 08 '18 at 03:54
  • I did not get _json does not exist in the context_. you said in OP that you able to return json from method, right ? however, solution i provided will basically return you response in deserialized format which you can use the way you want from consuming class/client etc. – rahulaga_dev Feb 08 '18 at 04:05
  • Yes, the HTTP Response message is has JSON so I use `JObject json = JObject.Parse(responsContent);` to parse it. However, when I use `return Deserialize(json);` then the message is "cannot convert JSON object". – EagleDev Feb 08 '18 at 04:07
  • you need to ensure your POCO entity to which your trying to convert to has property decorated with `[JsonProperty("jsonnameproperty")]` – rahulaga_dev Feb 08 '18 at 04:21
  • you can check for something similar [here](https://stackoverflow.com/questions/11126242/using-jsonconvert-deserializeobject-to-deserialize-json-to-a-c-sharp-poco-class) – rahulaga_dev Feb 08 '18 at 04:22
  • Thank you for your great advice. I appreciated it. Let me try it out! – EagleDev Feb 09 '18 at 14:14