예제 #1
0
        /// <summary>
        /// Builds a memory stream from the response body.
        /// </summary>
        /// <param name="response">Response message</param>
        /// <param name="acceptContentType">Content type to use for serialization</param>
        /// <param name="acceptEncoding">Response encoding</param>
        /// <returns>Memory stream from data serialized by content type</returns>
        private static MemoryStream BuildSuccessResponse(Response response, RequestContentType acceptContentType, Encoding acceptEncoding)
        {
            var bodyString = string.Empty;

            // If Body is null, just return empty response
            if (response?.Body == null)
            {
                return new MemoryStream(acceptEncoding.GetBytes(bodyString))
                       {
                           Position = 0
                       }
            }
            ;

            if (response.Body.Payload.XmlData != null)
            {
                switch (acceptContentType)
                {
                case RequestContentType.Json:

                    // Remove the namespace attributes:
                    response.Body.Payload.XmlData.Attributes.RemoveNamedItem("xmlns");
                    response.Body.Payload.XmlData.Attributes.RemoveNamedItem("xmlns:xsd");
                    response.Body.Payload.XmlData.Attributes.RemoveNamedItem("xmlns:xsi");
                    bodyString = Json.JsonConverter.ConvertFromXml(response.Body.Payload.XmlData);
                    break;

                case RequestContentType.Xml:
                    bodyString = response.Body.Payload.XmlData.OuterXml;
                    break;
                }
            }
            else if (!string.IsNullOrEmpty(response.Body.Payload.Data))
            {
                bodyString = XmlString.Decode(response.Body.Payload.Data);
            }

            return(new MemoryStream(acceptEncoding.GetBytes(bodyString))
            {
                Position = 0
            });
        }
        public async Task <Response> CallOperationAsync(Request request)
        {
            Response resp;

            // Send the request to the interface:
            HttpMethod requestMethod;
            UriBuilder url;
            var        bodyString = "";
            string     contentType;

            var httpClient = new HttpClient();

            try
            {
                // Settings defined in the input messages override the values set in the step parameters!

                // Set the request method:
                if (string.IsNullOrWhiteSpace(request.Method))
                {
                    requestMethod = _method ?? HttpMethod.Get;
                }
                else
                {
                    requestMethod = GetDeliveryMethod(request.Method);
                }

                // Set the base URL:
                url = string.IsNullOrWhiteSpace(request.Url?.BaseUrl)
                    ? new UriBuilder(_url)
                    : new UriBuilder(request.Url.BaseUrl);

                // Add the URL parameters:
                if (request.Url?.Query != null)
                {
                    var query = string.IsNullOrWhiteSpace(url.Query) ? "" : url.Query.Substring(1);

                    foreach (var parameter in request.Url.Query)
                    {
                        if (!string.IsNullOrWhiteSpace(query))
                        {
                            query += "&";
                        }
                        query += parameter.Name + "=" + parameter.Value;
                    }

                    url.Query = query;
                }

                // Set the content type:
                if (string.IsNullOrWhiteSpace(request.Body?.ContentType))
                {
                    contentType = string.IsNullOrWhiteSpace(_contentType)
                        ? "application/xml; charset=utf-8"
                        : _contentType;
                }
                else
                {
                    contentType = request.Body.ContentType;
                }


                // Get the body:
                if (request.Body?.Payload != null)
                {
                    if (request.Body.Payload.XmlData != null)
                    {
                        bodyString = contentType.Contains("application/json")
                            ? Json.JsonConverter.ConvertFromXml(request.Body.Payload.XmlData)
                            : request.Body.Payload.XmlData.OuterXml;
                    }
                    else if (request.Body.Payload.FormData != null && request.Body.Payload.FormData.Count > 0)
                    {
                        foreach (var param in request.Body.Payload.FormData)
                        {
                            if (!string.IsNullOrWhiteSpace(bodyString))
                            {
                                bodyString += "&";
                            }

                            bodyString += HttpUtility.UrlEncode(param.Name) + "=" + HttpUtility.UrlEncode(param.Value);
                        }
                    }
                    else if (!string.IsNullOrWhiteSpace(request.Body.Payload.Data))
                    {
                        bodyString = XmlString.Decode(request.Body.Payload.Data);
                    }
                }

                // Set authorization settings:
                if ((request.Authentication != null) &&
                    (request.Authentication.Type == AuthenticationType.Basic) &&
                    (request.Authentication.Credentials != null))
                {
                    var authorizationString = string.Join(":", request.Authentication.Credentials.UserName, request.Authentication.Credentials.Password);
                    var byteArray           = Encoding.ASCII.GetBytes(authorizationString);
                    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
                }
                else if ((AuthenticationType == AuthenticationType.Basic) &&
                         (Credentials != null))
                {
                    var authorizationString = string.Join(":", Credentials.UserName, Credentials.Password);
                    var byteArray           = Encoding.ASCII.GetBytes(authorizationString);
                    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
                }

                // Set the request headers:
                if (request.Headers != null)
                {
                    foreach (var h in request.Headers)
                    {
                        httpClient.DefaultRequestHeaders.Add(h.Name, h.Value);
                    }
                }

                // Set the timeout if it was defined:
                if (request.Timeout.HasValue)
                {
                    httpClient.Timeout = TimeSpan.FromSeconds(request.Timeout.Value);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Initializing the REST request failed.", ex);
            }


            HttpResponseMessage response;

            // Execute the REST request:
            using (httpClient)
            {
                try
                {
                    response = await ExecuteRestRequestAsync(httpClient, requestMethod, url.Uri, bodyString, contentType);
                }
                catch (Exception ex)
                {
                    throw new Exception("Sending the request failed.", ex);
                }

                if (((int)response.StatusCode < 200) || ((int)response.StatusCode >= 300))
                {
                    throw new Exception("The server responded with an error " + (int)response.StatusCode + ": " + response.ReasonPhrase);
                }
            }


            // Handle the response:
            try
            {
                resp = new Response {
                    Id = request.Id
                };

                using (response)
                {
                    resp.StatusCode    = ((int)response.StatusCode).ToString(CultureInfo.InvariantCulture);
                    resp.StatusMessage = response.ReasonPhrase;

                    // If the response has content, read it & convert it to XML if necessary
                    if (response.Content?.Headers?.ContentType?.MediaType != null)
                    {
                        using (var stream = await response.Content.ReadAsStreamAsync())
                            using (var reader = new StreamReader(stream))
                            {
                                resp.Body = new Body
                                {
                                    ContentType = response.Content.Headers.ContentType.MediaType,
                                    Encoding    = response.Content.Headers.ContentType.CharSet,
                                    Payload     = new Payload()
                                };

                                if (response.Content.Headers.ContentType.MediaType.StartsWith("application/json") ||
                                    response.Content.Headers.ContentType.MediaType.StartsWith("application/javascript") ||
                                    response.Content.Headers.ContentType.MediaType.StartsWith("application/x-json") ||
                                    response.Content.Headers.ContentType.MediaType.StartsWith("application/x-javascript") ||
                                    response.Content.Headers.ContentType.MediaType.StartsWith("text/json") ||
                                    response.Content.Headers.ContentType.MediaType.StartsWith("text/javascript") ||
                                    response.Content.Headers.ContentType.MediaType.StartsWith("text/x-json") ||
                                    response.Content.Headers.ContentType.MediaType.StartsWith("text/x-javascript"))
                                {
                                    // Convert JSON to XML

                                    // Read the response to a string:
                                    resp.Body.Payload.Data = await reader.ReadToEndAsync();

                                    // Convert the string to XML:
                                    var responseXml = Json.JsonConverter.ConvertToXml(resp.Body.Payload.Data);
                                    resp.Body.Payload.XmlData = responseXml.DocumentElement;
                                }
                                else if (response.Content.Headers.ContentType.MediaType.StartsWith("text/html"))
                                {
                                    // content-type text/html is a bit tricky. you never know what you get.
                                    // essentially we're making our own root-element, so the response can be xml/text/json/whateva
                                    var responseString = await reader.ReadToEndAsync();

                                    using (var xmlReader = XmlReader.Create(new StringReader(
                                                                                $"<Response>{System.Security.SecurityElement.Escape(responseString)}</Response>")))
                                    {
                                        var xmlDoc = new XmlDocument();
                                        xmlDoc.Load(xmlReader);
                                        resp.Body.Payload.XmlData = xmlDoc.DocumentElement;
                                    }
                                }
                                else
                                {
                                    // Read the response to XML:
                                    using (var xmlReader = XmlReader.Create(reader))
                                    {
                                        var xmlDoc = new XmlDocument();
                                        xmlDoc.Load(xmlReader);
                                        resp.Body.Payload.XmlData = xmlDoc.DocumentElement;
                                    }
                                }
                            }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Reading the response failed.", ex);
            }

            return(resp);
        }