Search code examples
c#asp.netasync-awaitbotframeworkdirect-line-botframework

HttpClient throws unexpected ThrowForNonSuccess


have following code that works with target framework .net core 2.2 with target framework 4.5 is has issues.

public async Task<string> GetConversationIdAsync()
    {
        try
        {
            var client = new HttpClient();
            var content = new StringContent(" ", Encoding.UTF8, "application/json");
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Authorization
                = new AuthenticationHeaderValue("Bearer", "XXXXXXXXXXXX");

            var response = await client.PostAsync(
                $"https://directline.botframework.com/v3/directline/conversations", content);///Error here

            var result = await response.Content.ReadAsStringAsync();
            return result;
        }
        catch (Exception ex)
        {

            throw;
        }

    }

This error coming: at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at OlyBot.Api.BLL.Handoff.d__1.MoveNext()

what is the issue here

i also tried to use

System.Net.WebRequest webRequest = System.Net.WebRequest.Create("https://directline.botframework.com/v3/directline/conversations");
                webRequest.Method = "POST";
                webRequest.Headers.Add("Authorization", "Bearer XXXXXXXXXXXXXX");
                webRequest.Headers.Add("Content-Type", "application/json");
                System.Net.WebResponse resp = webRequest.GetResponse();
                System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
                string result = sr.ReadToEnd().Trim();

But this also not working.


Solution

  • You can't set Content-Type as custom header, do this instead:

    webRequest.ContentType = "application/json";
    

    Also, you need to include Content-Length to a POST request:

    string content = " ";
    webRequest.ContentLength = content.Length;
    

    After that you need to write data:

      using (var streamWriter = new StreamWriter(webRequest.GetRequestStream()))
                {
                    streamWriter.Write(content);
                    streamWriter.Flush();
                    streamWriter.Close();
                }
    

    If your underlying connection getting closed, make sure to Initialize ServicePointManager, it will prevent the underlying connection from closing:

     public Form1()
            {
                 ServicePointManager.Expect100Continue = true;
                 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                 InitializeComponent();
            }
    

    So finally we have a request that looks like this:

    System.Net.WebRequest webRequest = System.Net.WebRequest.Create("https://directline.botframework.com/v3/directline/conversations");
            webRequest.Method = "POST";
            string content = " ";
            webRequest.Headers.Add("Authorization", "Bearer XXXXXXXXXXXXXX");
            webRequest.ContentType = "application/json";
            webRequest.ContentLength = content.Length;
            using (var streamWriter = new StreamWriter(webRequest.GetRequestStream()))
            {
                streamWriter.Write(content);
                streamWriter.Flush();
                streamWriter.Close();
            }
            System.Net.WebResponse resp = webRequest.GetResponse();
            System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
            string result = sr.ReadToEnd().Trim();
            sr.Close();
            resp.Close();
    

    You just need to use correct Authorization header otherwise you will get

    (403) forbidden

    response from the server.