/// <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); }