예제 #1
0
        /// <summary>
        /// Returns the string needed by the caller (JSON or XML depending on the content type specified)
        /// </summary>
        /// <param name="iStatusCode" type="HttpStatusCode" ref="false" inout="[in]" description="The http status of the error"/>
        /// <param name="sDescription" type="string" ref="false" inout="[in]" description="The error's description"/>
        /// <param name="sContentType" type="string" ref="false" inout="[in]" description="The type of data that the string is to be returned as (e.g. text/xml)"/>
        /// <returns>string (the error response)</returns>
        /// <history>
        /// <modified author="C. Gerard Gallant" date="2012-01-10" reason="Created"/>
        /// <modified author="C. Gerard Gallant" date="2012-10-10" reason="While doing some reading on Encoding.Default, I found that it is generally not recommended to to use (http://msdn.microsoft.com/en-us/library/system.text.encoding.default.aspx). I've modified it to use UTF8 instead. Turned out the issue we were seeing was an unexpected content-type value was being specified so now if the request wasn't for JSON, we return the error as XML."/>
        /// </history>
        protected static string BuildErrorReturnString(HttpStatusCode iStatusCode, string sDescription, string sContentType)
        {
            WebFaultExceptionDetails wfedContent = new WebFaultExceptionDetails(iStatusCode, sDescription);
            MemoryStream             msStream    = new MemoryStream();

            // If we're to return JSON data then...
            if (sContentType.Contains(MIME_TYPE_APPLICATION_JSON))
            {
                // Convert the object into a JSON string
                DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(WebFaultExceptionDetails));
                ser.WriteObject(msStream, wfedContent);
            }
            else // Any other type of request is assumed to be XML (just in case an unexpected type is requested, we don't want to return an empty string if there was an error)
            {
                // Convert the XML into a string
                DataContractSerializer ser = new DataContractSerializer(typeof(WebFaultExceptionDetails));
                ser.WriteObject(msStream, wfedContent);
            } // End if


            // Return the stream's content as a string
            return(Encoding.UTF8.GetString(msStream.ToArray()));
        }
        /// <summary>
        /// Returns the string needed by the caller (JSON or XML depending on the content type specified)
        /// </summary>
        /// <param name="iStatusCode" type="HttpStatusCode" ref="false" inout="[in]" description="The http status of the error"/>
        /// <param name="sDescription" type="string" ref="false" inout="[in]" description="The error's description"/>
        /// <param name="sContentType" type="string" ref="false" inout="[in]" description="The type of data that the string is to be returned as (e.g. text/xml)"/>
        /// <returns>string (the error response)</returns>
        /// <history>
        /// <modified author="C. Gerard Gallant" date="2012-01-10" reason="Created"/>
        /// <modified author="C. Gerard Gallant" date="2012-10-10" reason="While doing some reading on Encoding.Default, I found that it is generally not recommended to to use (http://msdn.microsoft.com/en-us/library/system.text.encoding.default.aspx). I've modified it to use UTF8 instead. Turned out the issue we were seeing was an unexpected content-type value was being specified so now if the request wasn't for JSON, we return the error as XML."/>
        /// </history>
        protected static string BuildErrorReturnString(HttpStatusCode iStatusCode, string sDescription, string sContentType)
        {
            WebFaultExceptionDetails wfedContent = new WebFaultExceptionDetails(iStatusCode, sDescription);
            MemoryStream msStream = new MemoryStream();

            // If we're to return JSON data then...
            if (sContentType.Contains(MIME_TYPE_APPLICATION_JSON))
            {
                // Convert the object into a JSON string
                DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(WebFaultExceptionDetails));
                ser.WriteObject(msStream, wfedContent);
            }
            else // Any other type of request is assumed to be XML (just in case an unexpected type is requested, we don't want to return an empty string if there was an error)
            {
                // Convert the XML into a string
                DataContractSerializer ser = new DataContractSerializer(typeof(WebFaultExceptionDetails));
                ser.WriteObject(msStream, wfedContent);
            } // End if

            // Return the stream's content as a string
            return Encoding.UTF8.GetString(msStream.ToArray());
        }
예제 #3
0
        /// <history>
        /// <modified author="C. Gerard Gallant" date="2012-04-23" reason="Created"/>
        /// <modified author="C. Gerard Gallant" date="2012-08-31" reason="Fixed an issue where if there are unicode characters in the content being sent, the content length was not set correctly. sPostPutData.Length is not good enough, need to pass the string through the Encoding.UTF8.GetByteCount function."/>
        /// <modified author="C. Gerard Gallant" date="2012-11-26" reason="A coworker is hitting the throttle limit of the API so an attempt to make things easier is being attempted here where we will re-try the call for a limited number of times before just returning with an error."/>
        /// </history>
        public static void MakeAPIRequest(APIRequestResult aRequestResult)
        {
            string sContentType = aRequestResult.ContentType;
            string sPostPutData = aRequestResult.RequestPostPutData;

            try
            {
                // Build up our request object
                HttpWebRequest hwrAPIRequest = (HttpWebRequest)WebRequest.Create(aRequestResult.GetRequestURI());
                hwrAPIRequest.Headers["Authorization"] = BuildAuthorizationHeaderContent(aRequestResult.ConsumerSecret, aRequestResult.DataAccessToken);
                hwrAPIRequest.Accept        = sContentType;
                hwrAPIRequest.Method        = aRequestResult.RequestHttpMethod;         // GET, PUT, POST, DELETE, etc
                hwrAPIRequest.ContentType   = sContentType;
                hwrAPIRequest.ContentLength = Encoding.UTF8.GetByteCount(sPostPutData); //Necessary if the string contains unicode characters

                // If there is data to be included with the request then...
                if (sPostPutData != "")
                {
                    // Get the request stream and write the body string to it
                    Stream       strOutput = hwrAPIRequest.GetRequestStream();
                    StreamWriter swWriter  = new StreamWriter(strOutput);
                    swWriter.Write(sPostPutData);

                    // Close our StreamWriter and Stream objects
                    swWriter.Flush(); // Make sure the buffers are pushed to the stream before we close the writer
                    swWriter.Close();

                    // I don't usually see this in StreamWriter examples but seeing that you can construct multiple StreamWriter objects on the same stream
                    // after flushing and closing the previous StreamWriter suggest to me that the stream is not closed by the Close call on StreamWriter. As
                    // a result, make sure our Stream object is closed. The MSDN examples for GetRequestStream DO close the stream when done.
                    strOutput.Close();
                } // End if (sPostPutData != "")


                // Make the request and get the response object
                HttpWebResponse hwrResponse = (HttpWebResponse)hwrAPIRequest.GetResponse();

                // Read in the response
                Stream       strResponse = hwrResponse.GetResponseStream();
                StreamReader srReader    = new StreamReader(strResponse);
                aRequestResult.RequestResult = srReader.ReadToEnd();
                srReader.Close();
                strResponse.Close();

                // Close the response object
                hwrResponse.Close();
            }
            catch (WebException weException)
            {
                HttpStatusCode iStatusCode  = HttpStatusCode.InternalServerError;
                string         sDescription = weException.Message;

                // If the exception was due to a protocol error (status code 300+) then...
                if (weException.Status == WebExceptionStatus.ProtocolError)
                {
                    // Grab the response, its Status Code, and the response stream
                    HttpWebResponse hwrResponse = (HttpWebResponse)weException.Response;
                    iStatusCode  = hwrResponse.StatusCode;
                    sDescription = hwrResponse.StatusDescription;

                    // If this is a throttle error and if we have not yet reached the maximum number of retries then...
                    if ((iStatusCode == HttpStatusCode.ServiceUnavailable) && (aRequestResult.RequestRetryCount < MAX_REQUEST_RETRY_COUNT))
                    {
                        // Sleep for 1 second
                        Thread.Sleep(1000);

                        // Increment our counter and make this request again. Exit so that the rest of this funtion doesn't execute.
                        aRequestResult.RequestRetryCount += 1;
                        MakeAPIRequest(aRequestResult);
                        return;
                    } // End if ((iStatusCode == HttpStatusCode.ServiceUnavailable) && (aRequestResult.RequestRetryCount < MAX_REQUEST_RETRY_COUNT))


                    Stream sResponseStream = hwrResponse.GetResponseStream();
                    WebFaultExceptionDetails wfedContent = null;

                    // If we are dealing with JSON then...
                    string sResponseContentType = hwrResponse.ContentType;
                    if (sResponseContentType.Contains(MIME_TYPE_APPLICATION_JSON))
                    {
                        // Convert the JSON string into an object and then grab it's description
                        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(WebFaultExceptionDetails));
                        wfedContent  = (WebFaultExceptionDetails)ser.ReadObject(sResponseStream);
                        sDescription = wfedContent.Description;
                    }
                    else if ((sResponseContentType.Contains(MIME_TYPE_TEXT_XML)) || (sResponseContentType.Contains(MIME_TYPE_APPLICATION_XML)))
                    {
                        // Convert the XML string into an object and then grab it's description
                        DataContractSerializer ser = new DataContractSerializer(typeof(WebFaultExceptionDetails));
                        wfedContent  = (WebFaultExceptionDetails)ser.ReadObject(sResponseStream);
                        sDescription = wfedContent.Description;
                    }
                    else // Not JSON and not XML (HTML?)...
                    {
                        // Grab the content data from the response object and then close the stream reader object
                        StreamReader srReader = new StreamReader(sResponseStream);
                        sDescription = srReader.ReadToEnd();
                        srReader.Close();
                    }// End if


                    // Close the response stream and then the response itself
                    sResponseStream.Close();
                    hwrResponse.Close();
                } // End if (weException.Status == WebExceptionStatus.ProtocolError)


                // Build up the return value for the caller for this error message.
                aRequestResult.SetRequestErrorMessage(iStatusCode, sDescription);
            } // End of the  catch (WebException weException) statement.
        }