/// <summary> /// Sends a web request with the data in the query string. /// </summary> /// <param name="url"> /// The URL to send the request to. /// </param> /// <param name="data"> /// The data to send. /// </param> /// <param name="method"> /// The HTTP method (e.g., GET, POST) to use when sending the request. /// </param> /// <returns> /// True, if the request was a success; otherwise, false. /// </returns> /// <remarks> /// Parts of this function are from: http://stackoverflow.com/a/9772003/2052963 and http://stackoverflow.com/questions/14702902 /// </remarks> private SendDataResult SendUrlEncodedRequest(string url, IEnumerable <KeyValuePair <string, string> > data, string method) { // Construct a URL containing the data as query string parameters. var sendDataResult = new SendDataResult(); var uri = new Uri(url); var queryString = HttpUtility.ParseQueryString(uri.Query); foreach (var pair in data) { queryString.Set(pair.Key, pair.Value); } var bareUrl = uri.GetLeftPart(UriPartial.Path); var strQueryString = queryString.ToString(); var hasQueryString = !string.IsNullOrWhiteSpace(strQueryString); var requestUrl = hasQueryString ? $"{bareUrl}?{strQueryString}" : url; ASCIIEncoding ascii = new ASCIIEncoding(); byte[] postBytes = ascii.GetBytes(queryString.ToString()); // Attempt to send the web request. try { var request = (HttpWebRequest)WebRequest.Create(requestUrl); request.AllowAutoRedirect = false; request.UserAgent = WebUserAgent; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = postBytes.Length; request.Method = method; // add post data to request Stream postStream = request.GetRequestStream(); postStream.Write(postBytes, 0, postBytes.Length); var response = (HttpWebResponse)request.GetResponse(); sendDataResult.HttpWebResponse = response; var responseStream = response.GetResponseStream(); var reader = new StreamReader(responseStream); var resultText = reader.ReadToEnd(); sendDataResult.ResponseText = resultText; sendDataResult.Success = true; } catch (Exception ex) { LogHelper.Error <SendDataHandler>(SendDataError, ex); sendDataResult.ResponseError = ex; sendDataResult.Success = false; } // Return the result of the request. return(sendDataResult); }
/// <summary> /// Sends a web request with the data either in the query string or in the body. /// </summary> /// <param name="config"> /// The configuration for the data to be sent (e.g., contains the URL and request method). /// </param> /// <param name="context"> /// The context for the current form submission. /// </param> /// <param name="data"> /// The data to send. /// </param> /// <param name="sendInBody"> /// Send the data as part of the body (or in the query string)? /// </param> /// <param name="sendJson"> /// Send the data as json /// </param> /// <returns> /// True, if the request was a success; otherwise, false. /// </returns> /// <remarks> /// Parts of this function are from: http://stackoverflow.com/a/9772003/2052963 /// and http://stackoverflow.com/questions/14702902 /// </remarks> private SendDataResult SendData(SendDataConfiguration config, FormSubmissionContext context, IEnumerable <KeyValuePair <string, string> > data, bool sendInBody, bool sendJson) { // Construct a URL, possibly containing the data as query string parameters. var sendInUrl = !sendInBody; var sendDataResult = new SendDataResult(); var uri = new Uri(config.Url); var bareUrl = uri.GetLeftPart(UriPartial.Path); var keyValuePairs = data as KeyValuePair <string, string>[] ?? data.ToArray(); var strQueryString = ConstructQueryString(uri, keyValuePairs); var hasQueryString = !string.IsNullOrWhiteSpace(strQueryString); var requestUrl = hasQueryString && sendInUrl ? $"{bareUrl}?{strQueryString}" : config.Url; var enableLogging = WebConfigurationManager.AppSettings["Formulate:EnableLogging"]; var jsonMode = WebConfigurationManager.AppSettings["Formulate:Send Data JSON Mode"]; var isJsonObjectMode = "JSON Object".InvariantEquals(jsonMode); var isWrappedObjectMode = "Wrap JSON Object in Array".InvariantEquals(jsonMode); // Attempt to send the web request. try { // Construct web request. var request = (HttpWebRequest)WebRequest.Create(requestUrl); request.AllowAutoRedirect = false; request.UserAgent = WebUserAgent; request.Method = config.Method; // Send an event indicating that the data is about to be sent (which allows code // external to Formulate to modify the request). var sendContext = new SendingDataContext() { Configuration = config, Data = keyValuePairs, Request = request, SubmissionContext = context }; SendingData?.Invoke(sendContext); // Update the key/value pairs in case they got changed in the sending data event. // This only updates the methods that send the data in the body (as the URL has // already been set on the request). keyValuePairs = sendContext.Data as KeyValuePair <string, string>[] ?? sendContext.Data.ToArray(); // Send the data in the body (rather than the query string)? if (sendInBody) { if (sendJson) { // Variables. var json = default(string); // Send an event indicating that the data is about to be serialized to // JSON (which allows code external to Formulate to modify the JSON)? if (SerializingJson != null) { json = SerializingJson.Invoke(sendContext.Data); } else { // If sending as JSON, group duplicate keys/value pairs. var grouped = keyValuePairs.GroupBy(x => x.Key).Select(x => new { Key = x.Key, Value = x.Select(y => y.Value) }).ToDictionary(x => x.Key, x => x.Value.Count() > 1 ? x.Value.ToArray() as object : x.Value.FirstOrDefault()); // Convert data to JSON. if (isJsonObjectMode) { json = JsonConvert.SerializeObject(grouped); } else if (isWrappedObjectMode) { json = JsonConvert.SerializeObject(new[] { grouped }); } else { // Ideally, we can remove this "else" branch later. We never really want this // mode to be used, but it's here for legacy support in case anybody managed // to make use of this funky mode. json = JsonConvert.SerializeObject(new[] { grouped }); } } // Log JSON being sent. if (enableLogging == "true") { LogHelper.Info <SendDataHandler>("Sent URL: " + config.Url); LogHelper.Info <SendDataHandler>("Sent Data: " + JsonHelper.FormatJsonForLogging(json)); } // Write JSON data to the request request. var postBytes = Encoding.UTF8.GetBytes(json); request.ContentType = "application/json; charset=utf-8"; request.ContentLength = postBytes.Length; using (var postStream = request.GetRequestStream()) { postStream.Write(postBytes, 0, postBytes.Length); } } else { // Log data being sent. if (enableLogging == "true") { LogHelper.Info <SendDataHandler>("Sent URL: " + config.Url); LogHelper.Info <SendDataHandler>("Sent Data: " + strQueryString); } // Update the data (since the sending data event may have modified it). uri = new Uri(config.Url); strQueryString = ConstructQueryString(uri, keyValuePairs); // Write the data to the request stream. var postBytes = Encoding.UTF8.GetBytes(strQueryString); request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = postBytes.Length; var postStream = request.GetRequestStream(); postStream.Write(postBytes, 0, postBytes.Length); } } // Get and retain response. var response = (HttpWebResponse)request.GetResponse(); sendDataResult.HttpWebResponse = response; var responseStream = response.GetResponseStream(); var reader = new StreamReader(responseStream); var resultText = reader.ReadToEnd(); sendDataResult.ResponseText = resultText; sendDataResult.Success = true; } catch (Exception ex) { LogHelper.Error <SendDataHandler>(SendDataError, ex); sendDataResult.ResponseError = ex; sendDataResult.Success = false; } // Return the result of the request. return(sendDataResult); }
/// <summary> /// Sends a web request with the data either in the query string or in the body. /// </summary> /// <param name="url"> /// The URL to send the request to. /// </param> /// <param name="data"> /// The data to send. /// </param> /// <param name="method"> /// The HTTP method (e.g., GET, POST) to use when sending the request. /// </param> /// <param name="sendInBody"> /// Send the data as part of the body (or in the query string)? /// </param> /// <param name="sendJson"> /// Send the data as json /// </param> /// <returns> /// True, if the request was a success; otherwise, false. /// </returns> /// <remarks> /// Parts of this function are from: http://stackoverflow.com/a/9772003/2052963 /// and http://stackoverflow.com/questions/14702902 /// </remarks> private SendDataResult SendData(string url, IEnumerable <KeyValuePair <string, string> > data, string method, bool sendInBody, bool sendJson) { // Construct a URL, possibly containing the data as query string parameters. var sendInUrl = !sendInBody; var sendDataResult = new SendDataResult(); var uri = new Uri(url); var bareUrl = uri.GetLeftPart(UriPartial.Path); var strQueryString = ConstructQueryString(uri, data); var hasQueryString = !string.IsNullOrWhiteSpace(strQueryString); var requestUrl = hasQueryString && sendInUrl ? $"{bareUrl}?{strQueryString}" : url; // Attempt to send the web request. try { // Construct web request. var request = (HttpWebRequest)WebRequest.Create(requestUrl); request.AllowAutoRedirect = false; request.UserAgent = WebUserAgent; request.Method = method; // Send the data in the body (rather than the query string)? if (sendInBody) { if (sendJson) { // if sending as json // Group duplicate Key Name Pair values var grouped = data.GroupBy(x => x.Key).Select(x => new { Key = x.Key, Value = x.Select(y => y.Value) }).ToDictionary(x => x.Key, x => x.Value.Count() > 1 ? x.Value.ToArray() as object : x.Value.FirstOrDefault());; var json = JsonConvert.SerializeObject(new [] { grouped }); // log json being sent var enableLogging = WebConfigurationManager.AppSettings["Formulate:EnableLogging"]; if (enableLogging == "true") { LogHelper.Info <SendDataHandler>("{0}", () => json); } var postBytes = Encoding.UTF8.GetBytes(json); request.ContentType = "application/json; charset=utf-8"; request.ContentLength = postBytes.Length; var postStream = request.GetRequestStream(); postStream.Write(postBytes, 0, postBytes.Length); } else { var postBytes = Encoding.UTF8.GetBytes(strQueryString); request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = postBytes.Length; var postStream = request.GetRequestStream(); postStream.Write(postBytes, 0, postBytes.Length); } } // Get and retain response. var response = (HttpWebResponse)request.GetResponse(); sendDataResult.HttpWebResponse = response; var responseStream = response.GetResponseStream(); var reader = new StreamReader(responseStream); var resultText = reader.ReadToEnd(); sendDataResult.ResponseText = resultText; sendDataResult.Success = true; } catch (Exception ex) { LogHelper.Error <SendDataHandler>(SendDataError, ex); sendDataResult.ResponseError = ex; sendDataResult.Success = false; } // Return the result of the request. return(sendDataResult); }