public override async Task BeginDialogAsync()

in libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/HttpRequest.cs [217:405]


        public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (options is CancellationToken)
            {
                throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
            }

            if (Disabled != null && Disabled.GetValue(dc.State))
            {
                return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
            }

            // This is injected for testing, and should not be used for anything else.
            var client = dc.Context.TurnState.Get<HttpClient>();

            var disposeHttpClient = false;
            if (client == null)
            {
                disposeHttpClient = true;

                //Note: this should also be analyzed once we start using HttpClientFactory.
#pragma warning disable CA2000 // Dispose objects before losing scope
                client = new HttpClient();
#pragma warning restore CA2000 // Dispose objects before losing scope
            }

            try
            {
                var instanceBody = Body?.EvaluateExpression(dc.State);

                var instanceHeaders = Headers == null ? null : Headers.ToDictionary(kv => kv.Key, kv => kv.Value.GetValue(dc.State));

                var (instanceUrl, instanceUrlError) = Url.TryGetValue(dc.State);
                if (instanceUrlError != null)
                {
                    throw new ArgumentException(instanceUrlError);
                }

                using HttpRequestMessage request = new HttpRequestMessage(new System.Net.Http.HttpMethod(Method.ToString()), instanceUrl);

                // Set headers
                if (instanceHeaders != null)
                {
                    foreach (var unit in instanceHeaders)
                    {
                        request.Headers.TryAddWithoutValidation(unit.Key, unit.Value);
                    }
                }

                request.Headers.TryAddWithoutValidation("user-agent", "Mozilla/5.0");

                dynamic traceInfo = new JObject();

                traceInfo.request = new JObject();
                traceInfo.request.method = Method.ToString();
                traceInfo.request.url = instanceUrl;

                HttpResponseMessage response = null;
                string contentType = ContentType?.GetValue(dc.State) ?? "application/json";

                switch (Method)
                {
                    case HttpMethod.POST:
                        if (instanceBody == null)
                        {
                            response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
                        }
                        else
                        {
                            using var postContent = new StringContent(instanceBody.ToString(), Encoding.UTF8, contentType);
                            traceInfo.request.content = instanceBody.ToString();
                            request.Content = postContent;
                            traceInfo.request.headers = JObject.FromObject(request.Content.Headers.ToDictionary(t => t.Key, t => (object)t.Value?.FirstOrDefault()));
                            response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
                        }

                        break;

                    case HttpMethod.PATCH:
                        if (instanceBody == null)
                        {
                            response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
                        }
                        else
                        {
                            using var patchContent = new StringContent(instanceBody.ToString(), Encoding.UTF8, contentType);
                            request.Content = patchContent;
                            traceInfo.request.content = instanceBody.ToString();
                            traceInfo.request.headers = JObject.FromObject(request.Content.Headers.ToDictionary(t => t.Key, t => (object)t.Value?.FirstOrDefault()));
                            response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
                        }

                        break;

                    case HttpMethod.PUT:
                        if (instanceBody == null)
                        {
                            response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
                        }
                        else
                        {
                            using var putContent = new StringContent(instanceBody.ToString(), Encoding.UTF8, contentType);
                            traceInfo.request.content = instanceBody.ToString();
                            request.Content = putContent;
                            traceInfo.request.headers = JObject.FromObject(request.Content.Headers.ToDictionary(t => t.Key, t => (object)t.Value?.FirstOrDefault()));
                            response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
                        }

                        break;

                    case HttpMethod.DELETE:
                        response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
                        break;

                    case HttpMethod.GET:
                        response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
                        break;
                }

                var requestResult = new Result(response.Headers)
                {
                    StatusCode = (int)response.StatusCode,
                    ReasonPhrase = response.ReasonPhrase,
                };

                object content = (object)await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                switch (ResponseType.GetValue(dc.State))
                {
                    case ResponseTypes.Activity:
                        var activity = JsonConvert.DeserializeObject<Activity>((string)content);
                        requestResult.Content = JObject.FromObject(activity);
                        await dc.Context.SendActivityAsync(activity, cancellationToken: cancellationToken).ConfigureAwait(false);
                        break;

                    case ResponseTypes.Activities:
                        var activities = JsonConvert.DeserializeObject<Activity[]>((string)content);
                        requestResult.Content = JArray.FromObject(activities);
                        await dc.Context.SendActivitiesAsync(activities, cancellationToken: cancellationToken).ConfigureAwait(false);
                        break;

                    case ResponseTypes.Json:
                        // Try set with JOjbect for further retrieving
                        try
                        {
                            content = JToken.Parse((string)content);
                        }
#pragma warning disable CA1031 // Do not catch general exception types (just stringify the content if we can't parse the content).
                        catch
#pragma warning restore CA1031 // Do not catch general exception types
                        {
                            content = content.ToString();
                        }

                        requestResult.Content = content;
                        break;

                    case ResponseTypes.Binary:
                        // Try to resolve binary data
                        var bytes = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
                        requestResult.Content = bytes;
                        break;

                    case ResponseTypes.None:
                    default:
                        break;
                }

                traceInfo.response = JObject.FromObject(requestResult);

                // Write Trace Activity for the http request and response values
                await dc.Context.TraceActivityAsync("HttpRequest", (object)traceInfo, valueType: "Microsoft.HttpRequest", label: Id).ConfigureAwait(false);

                if (ResultProperty != null)
                {
                    dc.State.SetValue(ResultProperty.GetValue(dc.State), requestResult);
                }

                // return the actionResult as the result of this operation
                return await dc.EndDialogAsync(result: requestResult, cancellationToken: cancellationToken).ConfigureAwait(false);
            }
            finally
            {
                if (disposeHttpClient)
                {
                    client.Dispose();
                }
            }
        }