Esempio n. 1
0
        /// <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);
        }