internal void SendRequest2()
        {
            try
            {
                if (AbstractRequest == null)
                {
                    throw new ApiException("RequestType reference not set to an instance of an object.", new System.ArgumentNullException());
                }
                if (ApiContext == null)
                {
                    throw new ApiException("ApiContext reference not set to an instance of an object.", new System.ArgumentNullException());
                }
                if (ApiContext.ApiCredential == null)
                {
                    throw new ApiException("Credentials reference in ApiContext object not set to an instance of an object.", new System.ArgumentNullException());
                }



                string apiName     = AbstractRequest.GetType().Name.Replace("RequestType", "");
                var    requestName = Type.GetType("eBay.Service.Core.Soap." + apiName + "Request");


                if (this.ApiContext.EnableMetrics)
                {
                    mCallMetrics = this.ApiContext.CallMetricsTable.GetNewEntry(apiName);
                    mCallMetrics.ApiCallStarted = System.DateTime.Now;
                }


                string url = "";
                try
                {
                    if (ApiContext.SoapApiServerUrl != null && ApiContext.SoapApiServerUrl.Length > 0)
                    {
                        url = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}?callname={1}&siteid={2}&client=netsoap",
                                            ApiContext.SoapApiServerUrl, apiName, SiteUtility.GetSiteID(Site).ToString(System.Globalization.CultureInfo.InvariantCulture));
                    }
                    else
                    {
                        url = "https://api.ebay.com/wsapi";
                        url = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}?callname={1}&siteid={2}&client=netsoap",
                                            url, apiName, SiteUtility.GetSiteID(Site).ToString(System.Globalization.CultureInfo.InvariantCulture));
                    }
                }
                catch (Exception ex)
                {
                    throw new ApiException(ex.Message, ex);
                }

                LogMessage(url, MessageType.Information, MessageSeverity.Informational);



                //mEnableCompression//数据压缩
                //moAuthToken//moAuthToken授权//
                //mWebProxy//代理
                //mCallMetrics速度监控



                var eBayAPIInterfaceClient = eBayAPIInstance.Instance.GeteBayAPIClient(url, timeout: this.Timeout);
                //var 报文 = new 报文();
                //eBayAPIInterfaceClient.Endpoint.EndpointBehaviors.Add(new ContextPropagationBehavior(报文));
                //PropertyInfo pi;

                //pi = this.mServiceType.GetProperty("ApiLogManager");
                //if (pi == null)
                //    throw new SdkException("ApiLogManager was not found in InterfaceServiceType");
                //pi.SetValue(svcInst, this.mApiContext.ApiLogManager, null);

                //pi = this.mServiceType.GetProperty("EnableComression");
                //if (pi == null)
                //    throw new SdkException("EnableComression was not found in InterfaceServiceType");
                //pi.SetValue(svcInst, this.mEnableCompression, null);

                //Add oAuth
                //if (pi == null)
                //    throw new SdkException("RequesterCredentials was not found in InterfaceServiceType");
                //pi.SetValue(svcInst, this., null);
                //if (string.IsNullOrEmpty(this.ApiContext.ApiCredential.oAuthToken))
                //{
                //    pi = this.mServiceType.GetProperty("RequesterCredentials");
                //    if (pi == null)
                //        throw new SdkException("RequesterCredentials was not found in InterfaceServiceType");
                //    pi.SetValue(svcInst, secHdr, null);
                //}

                //pi = this.mServiceType.GetProperty("WebProxy");
                //if (pi == null)
                //    throw new SdkException("WebProxy was not found in InterfaceServiceType");
                //pi.SetValue(svcInst, this.mApiContext.WebProxy, null);
                //if (this.mApiContext.WebProxy != null)
                //{
                //    LogMessage("Proxy Server is Set", MessageType.Information, MessageSeverity.Informational);
                //}

                //pi = this.mServiceType.GetProperty("CallMetricsEntry");
                //if (pi == null)
                //    throw new SdkException("CallMetricsEntry was not found in InterfaceServiceType");
                //if (this.ApiContext.EnableMetrics)
                //    pi.SetValue(svcInst, this.mCallMetrics, null);
                //else
                //    pi.SetValue(svcInst, null, null);

                //pi = this.mServiceType.GetProperty("OAuthToken");
                //if (!string.IsNullOrEmpty(this.ApiContext.ApiCredential.oAuthToken))
                //{
                //    this.mOAuth = this.ApiContext.ApiCredential.oAuthToken;
                //    pi.SetValue(svcInst, this.OAuth, null);
                //}



                ////svcCCTor.Timeout = Timeout;
                //this.mServiceType.GetProperty("Timeout").SetValue(svcInst, Timeout, null);

                AbstractRequest.Version = Version;

                if (!mDetailLevelOverride && AbstractRequest.DetailLevel == null)
                {
                    AbstractRequest.DetailLevel = mDetailLevelList;
                }

                //Added OutputSelector to base call JIRA-SDK-561
                AbstractRequest.OutputSelector = mOutputSelector;

                if (ApiContext.ErrorLanguage != ErrorLanguageCodeType.CustomCode)
                {
                    AbstractRequest.ErrorLanguage = ApiContext.ErrorLanguage.ToString();
                }

                //Populate the message
                AbstractRequest.MessageID = System.Guid.NewGuid().ToString();

                //Type methodtype = svcInst.GetType();
                //object[] reqparm = new object[] { AbstractRequest };

                CustomSecurityHeaderType secHdr = this.GetSecurityHeader();
                var request = System.Activator.CreateInstance(requestName);
                requestName.GetProperty("RequesterCredentials").SetValue(request, secHdr);
                requestName.GetProperty(apiName + "RequestType").SetValue(request, AbstractRequest);
                //, secHdr, this.AbstractRequest
                int       retries    = 0;
                int       maxRetries = 0;
                bool      doretry    = false;
                CallRetry retry      = null;
                if (mCallRetry != null)
                {
                    retry      = mCallRetry;
                    maxRetries = retry.MaximumRetries;
                }
                else if (ApiContext.CallRetry != null)
                {
                    retry      = ApiContext.CallRetry;
                    maxRetries = retry.MaximumRetries;
                }



                do
                {
                    Exception callException = null;
                    try
                    {
                        //        mResponse = null;
                        //        mApiException = null;

                        if (retries > 0)
                        {
                            LogMessage("Invoking Call Retry", MessageType.Information, MessageSeverity.Informational);
                            System.Threading.Thread.Sleep(retry.DelayTime);
                        }

                        if (BeforeRequest != null)
                        {
                            BeforeRequest(this, new BeforeRequestEventArgs(AbstractRequest));
                        }


                        //Invoke the Service
                        DateTime start = DateTime.Now;
                        //mResponse = (AbstractResponseType)methodtype.GetMethod(apiName).Invoke(svcInst, reqparm);

                        if (mCallMetrics != null)
                        {
                            mCallMetrics.NetworkSendStarted = DateTime.Now;
                            //request.Headers.Add("X-EBAY-API-METRICS", "true");
                        }
                        var response = eBayAPIInterfaceClient.GetType().GetMethod(apiName).Invoke(eBayAPIInterfaceClient, new[] { request });

                        mResponse = (AbstractResponseType)response.GetType().GetProperty(apiName + "ResponseType").GetValue(response);
                        if (mCallMetrics != null)
                        {
                            mCallMetrics.NetworkReceiveEnded = DateTime.Now;
                            //mCallMetrics.ServerProcessingTime = convertProcessingTime(response.Headers.Get("X-EBAY-API-PROCESS-TIME"));
                        }
                        //validate(response.StatusCode);
                        mResponseTime = DateTime.Now - start;

                        if (AfterRequest != null)
                        {
                            AfterRequest(this, new AfterRequestEventArgs(mResponse));
                        }

                        // Catch Token Expiration warning
                        if (mResponse != null && secHdr.HardExpirationWarning != null)
                        {
                            ApiContext.ApiCredential.TokenHardExpirationWarning(
                                System.Convert.ToDateTime(secHdr.HardExpirationWarning, System.Globalization.CultureInfo.CurrentUICulture));
                        }


                        if (mResponse != null && mResponse.Errors != null && mResponse.Errors.Count > 0)
                        {
                            throw new ApiException(new List <ErrorType>(mResponse.Errors));
                        }
                    }

                    catch (Exception ex)
                    {
                        // this catches soap faults
                        if (ex.GetType() == typeof(TargetInvocationException))
                        {
                            // we never care about the outer exception
                            Exception iex = ex.InnerException;

                            //// Parse Soap Faults
                            //if (iex.GetType() == typeof(SoapException))
                            //{
                            //    ex = ApiException.FromSoapException((SoapException)iex);
                            //}
                            //else
                            if (iex.GetType() == typeof(InvalidOperationException))
                            {
                                // Go to innermost exception
                                while (iex.InnerException != null)
                                {
                                    iex = iex.InnerException;
                                }
                                ex = new ApiException(iex.Message, iex);
                            }
                            else if (iex.GetType() == typeof(HttpException))
                            {
                                HttpException httpEx = (HttpException)iex;
                                String        str    = "HTTP Error Code: " + httpEx.StatusCode;
                                ex = new ApiException(str, iex);
                            }
                            else
                            {
                                ex = new ApiException(iex.Message, iex);
                            }
                        }
                        callException = ex;

                        // log the message - override current switches - *if* (a) we wouldn't normally log it, and (b)
                        // the exception matches the exception filter.

                        if (retry != null)
                        {
                            doretry = retry.ShouldRetry(ex);
                        }

                        if (!doretry || retries == maxRetries)
                        {
                            throw ex;
                        }
                        else
                        {
                            //string soapReq = 报文.发送.LastOrDefault();//  (string)this.mServiceType.GetProperty("SoapRequest").GetValue(svcInst, null);
                            //string soapResp = 报文.接收.LastOrDefault(); // (string)this.mServiceType.GetProperty("SoapResponse").GetValue(svcInst, null);

                            //LogMessagePayload(soapReq + "\r\n\r\n" + soapResp, MessageSeverity.Informational, ex);
                            MessageSeverity svr = ((ApiException)ex).SeverityErrorCount > 0 ? MessageSeverity.Error : MessageSeverity.Warning;
                            LogMessage(ex.Message, MessageType.Exception, svr);
                        }
                    }

                    finally
                    {
                        //string soapReq = 报文.发送.LastOrDefault();// (string)this.mServiceType.GetProperty("SoapRequest").GetValue(svcInst, null);
                        //string soapResp = 报文.接收.LastOrDefault(); //(string)this.mServiceType.GetProperty("SoapResponse").GetValue(svcInst, null);

                        //if (!doretry || retries == maxRetries)
                        //    LogMessagePayload(soapReq + "\r\n\r\n" + soapResp, MessageSeverity.Informational, callException);

                        if (mResponse != null && mResponse.Timestamp.HasValue)
                        {
                            ApiContext.CallUpdate(mResponse.Timestamp.Value);
                        }
                        else
                        {
                            ApiContext.CallUpdate(new DateTime(0));
                        }

                        //mSoapRequest = soapReq;
                        //mSoapResponse = soapResp;
                        retries++;



                        //var ssss = System.Xml.Linq.XElement.Parse(soapResp);
                        //var sdfsdfdsf = ssss.Elements().LastOrDefault().FirstNode.ToString();

                        //var ser = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(eBay.Service.Core.Soap.GetApiAccessRulesResponseType), "GetApiAccessRulesResponse");
                        //using (var ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(sdfsdfdsf)))
                        //{
                        //    var jsonObject = ser.ReadObject(ms);
                        //}
                    }
                } while (doretry && retries <= maxRetries);
            }

            catch (Exception ex)
            {
                ApiException aex = ex as ApiException;

                if (aex != null)
                {
                    mApiException = aex;
                }
                else
                {
                    mApiException = new ApiException(ex.Message, ex);
                }
                MessageSeverity svr = mApiException.SeverityErrorCount > 0 ? MessageSeverity.Error : MessageSeverity.Warning;
                LogMessage(mApiException.Message, MessageType.Exception, svr);

                if (mApiException.SeverityErrorCount > 0)
                {
                    throw mApiException;
                }
            }
            finally
            {
                if (this.ApiContext.EnableMetrics)
                {
                    mCallMetrics.ApiCallEnded = DateTime.Now;
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Method to post picture data with HttpWebRequest
        /// </summary>
        /// <param name="fileName">the full path of the picture file to be uploaded</param>
        /// <param name="requestXmlString">request xml string</param>
        /// <returns>response string</returns>

        private string sendFile(string fileName, string requestXmlString)
        {
            const string BOUNDARY = "MIME_boundary";
            const string CRLF     = "\r\n";

            //get HttpWebRequest object
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(this.ApiContext.EPSServerUrl);

            req.Method          = "POST";
            req.ProtocolVersion = HttpVersion.Version11;

            //set proxy server if necessary
            if (this.ApiContext.WebProxy != null)
            {
                req.Proxy = this.ApiContext.WebProxy;
            }

            //set http headers
            req.Headers.Add("X-EBAY-API-COMPATIBILITY-LEVEL", this.ApiContext.Version);
            req.Headers.Add("X-EBAY-API-SITEID", SiteUtility.GetSiteID(this.ApiContext.Site).ToString());
            req.Headers.Add("X-EBAY-API-DETAIL-LEVEL", X_EBAY_API_DETAIL_LEVEL);
            req.Headers.Add("X-EBAY-API-CALL-NAME", X_EBAY_API_CALL_NAME);
            req.ContentType = "multipart/form-data; boundary=" + BOUNDARY;

            //Check for oAuth - Sree 11/14/2017.
            if (!String.IsNullOrEmpty(this.ApiContext.ApiCredential.oAuthToken))
            {
                req.Headers.Add("X-EBAY-API-IAF-TOKEN", this.ApiContext.ApiCredential.oAuthToken);
            }

            //read in the picture file
            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);

            fs.Seek(0, SeekOrigin.Begin);
            BinaryReader br = new BinaryReader(fs);

            byte[] image = br.ReadBytes((int)fs.Length);
            br.Close();
            fs.Close();

            //first part of the post body
            string strReq1 = "--" + BOUNDARY + CRLF
                             + "Content-Disposition: form-data; name=document" + CRLF
                             + "Content-Type: text/xml; charset=\"UTF-8\"" + CRLF + CRLF
                             + requestXmlString
                             + CRLF + "--" + BOUNDARY + CRLF
                             + "Content-Disposition: form-data; name=image; filename=image" + CRLF
                             + "Content-Transfer-Encoding: binary" + CRLF
                             + "Content-Type: application/octet-stream" + CRLF + CRLF;

            //last part of the post body
            string strReq2 = CRLF + "--" + BOUNDARY + "--" + CRLF;

            //log request message to eps server
            string reqInfo = "UploadSiteHostedPicturesRequest to " + this.ApiContext.EPSServerUrl;

            LogMessage(reqInfo, MessageType.Information, MessageSeverity.Informational);
            string reqMsg = Util.XmlUtility.FormatXml(requestXmlString) + CRLF + CRLF;

            reqMsg = System.Text.RegularExpressions.Regex.Replace(reqMsg, "<eBayAuthToken>.+</eBayAuthToken>", "<eBayAuthToken>******</eBayAuthToken>");
            LogMessage(reqMsg, MessageType.ApiMessage, MessageSeverity.Informational);

            //Convert string to byte array
            byte[] postDataBytes1 = System.Text.Encoding.ASCII.GetBytes(strReq1);
            byte[] postDataBytes2 = System.Text.Encoding.ASCII.GetBytes(strReq2);

            int len = postDataBytes1.Length + postDataBytes2.Length + image.Length;

            req.ContentLength = len;

            //post the payload
            Stream requestStream = req.GetRequestStream();

            requestStream.Write(postDataBytes1, 0, postDataBytes1.Length);
            requestStream.Write(image, 0, image.Length);
            requestStream.Write(postDataBytes2, 0, postDataBytes2.Length);
            requestStream.Close();

            //get response and write to console
            HttpWebResponse resp           = (HttpWebResponse)req.GetResponse();
            StreamReader    responseReader = new StreamReader(resp.GetResponseStream(), Encoding.UTF8);
            string          response       = responseReader.ReadToEnd();

            //log response message from eps server
            string respInfo = "UploadSiteHostedPicturesResponse from " + this.ApiContext.EPSServerUrl;

            LogMessage(respInfo, MessageType.Information, MessageSeverity.Informational);
            string respMsg = Util.XmlUtility.FormatXml(response) + CRLF + CRLF;

            LogMessage(respMsg, MessageType.ApiMessage, MessageSeverity.Informational);
            resp.Close();

            return(response);
        }
Exemple #3
0
        /// <summary>
        ///
        /// </summary>
        internal void SendRequest()
        {
            try
            {
                if (AbstractRequest == null)
                {
                    throw new ApiException("RequestType reference not set to an instance of an object.", new System.ArgumentNullException());
                }
                if (ApiContext == null)
                {
                    throw new ApiException("ApiContext reference not set to an instance of an object.", new System.ArgumentNullException());
                }
                if (ApiContext.ApiCredential == null)
                {
                    throw new ApiException("Credentials reference in ApiContext object not set to an instance of an object.", new System.ArgumentNullException());
                }

                string apiName = AbstractRequest.GetType().Name.Replace("RequestType", "");

                if (this.ApiContext.EnableMetrics)
                {
                    mCallMetrics = this.ApiContext.CallMetricsTable.GetNewEntry(apiName);
                    mCallMetrics.ApiCallStarted = System.DateTime.Now;
                }

                CustomSecurityHeaderType secHdr = this.GetSecurityHeader();

                // Get default constructor.

                /*
                 * ConstructorInfo svcCCTor = this.mServiceType.GetConstructor(
                 *  BindingFlags.Instance | BindingFlags.Public, null,
                 *  CallingConventions.HasThis, null, null);
                 */
                ConstructorInfo svcCCTor = this.mServiceType.GetConstructor(new Type[] { });

                object svcInst = svcCCTor.Invoke(null);

                PropertyInfo pi;

                pi = this.mServiceType.GetProperty("ApiLogManager");
                if (pi == null)
                {
                    throw new SdkException("ApiLogManager was not found in InterfaceServiceType");
                }
                pi.SetValue(svcInst, this.mApiContext.ApiLogManager, null);

                pi = this.mServiceType.GetProperty("EnableComression");
                if (pi == null)
                {
                    throw new SdkException("EnableComression was not found in InterfaceServiceType");
                }
                pi.SetValue(svcInst, this.mEnableCompression, null);

                //Add oAuth
                //if (pi == null)
                //    throw new SdkException("RequesterCredentials was not found in InterfaceServiceType");
                //pi.SetValue(svcInst, this., null);
                if (string.IsNullOrEmpty(this.ApiContext.ApiCredential.oAuthToken))
                {
                    pi = this.mServiceType.GetProperty("RequesterCredentials");
                    if (pi == null)
                    {
                        throw new SdkException("RequesterCredentials was not found in InterfaceServiceType");
                    }
                    pi.SetValue(svcInst, secHdr, null);
                }

                pi = this.mServiceType.GetProperty("WebProxy");
                if (pi == null)
                {
                    throw new SdkException("WebProxy was not found in InterfaceServiceType");
                }
                pi.SetValue(svcInst, this.mApiContext.WebProxy, null);
                if (this.mApiContext.WebProxy != null)
                {
                    LogMessage("Proxy Server is Set", MessageType.Information, MessageSeverity.Informational);
                }

                pi = this.mServiceType.GetProperty("CallMetricsEntry");
                if (pi == null)
                {
                    throw new SdkException("CallMetricsEntry was not found in InterfaceServiceType");
                }
                if (this.ApiContext.EnableMetrics)
                {
                    pi.SetValue(svcInst, this.mCallMetrics, null);
                }
                else
                {
                    pi.SetValue(svcInst, null, null);
                }

                pi = this.mServiceType.GetProperty("OAuthToken");
                if (!string.IsNullOrEmpty(this.ApiContext.ApiCredential.oAuthToken))
                {
                    this.mOAuth = this.ApiContext.ApiCredential.oAuthToken;
                    pi.SetValue(svcInst, this.OAuth, null);
                }

                string url = "";
                try
                {
                    if (ApiContext.SoapApiServerUrl != null && ApiContext.SoapApiServerUrl.Length > 0)
                    {
                        url = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}?callname={1}&siteid={2}&client=netsoap",
                                            ApiContext.SoapApiServerUrl, apiName, SiteUtility.GetSiteID(Site).ToString(System.Globalization.CultureInfo.InvariantCulture));
                    }
                    else
                    {
                        url = (string)this.mServiceType.GetProperty("Url").GetValue(svcInst, null);
                        url = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}?callname={1}&siteid={2}&client=netsoap",
                                            url, apiName, SiteUtility.GetSiteID(Site).ToString(System.Globalization.CultureInfo.InvariantCulture));
                    }

                    //svcCCTor.Url = url;
                    this.mServiceType.GetProperty("Url").SetValue(svcInst, url, null);
                }
                catch (Exception ex)
                {
                    throw new ApiException(ex.Message, ex);
                }

                LogMessage(url, MessageType.Information, MessageSeverity.Informational);

                //svcCCTor.Timeout = Timeout;
                this.mServiceType.GetProperty("Timeout").SetValue(svcInst, Timeout, null);

                AbstractRequest.Version = Version;

                if (!mDetailLevelOverride && AbstractRequest.DetailLevel == null)
                {
                    AbstractRequest.DetailLevel = new DetailLevelCodeTypeCollection();
                    AbstractRequest.DetailLevel.AddRange(mDetailLevelList);
                }

                //Added OutputSelector to base call JIRA-SDK-561
                AbstractRequest.OutputSelector = new StringCollection();
                AbstractRequest.OutputSelector.AddRange(mOutputSelector);

                if (ApiContext.ErrorLanguage != ErrorLanguageCodeType.CustomCode)
                {
                    AbstractRequest.ErrorLanguage = ApiContext.ErrorLanguage.ToString();
                }

                //Populate the message
                AbstractRequest.MessageID = System.Guid.NewGuid().ToString();

                Type     methodtype = svcInst.GetType();
                object[] reqparm    = new object[] { AbstractRequest };

                int       retries    = 0;
                int       maxRetries = 0;
                bool      doretry    = false;
                CallRetry retry      = null;
                if (mCallRetry != null)
                {
                    retry      = mCallRetry;
                    maxRetries = retry.MaximumRetries;
                }
                else if (ApiContext.CallRetry != null)
                {
                    retry      = ApiContext.CallRetry;
                    maxRetries = retry.MaximumRetries;
                }


                do
                {
                    Exception callException = null;
                    try
                    {
                        mResponse     = null;
                        mApiException = null;

                        if (retries > 0)
                        {
                            LogMessage("Invoking Call Retry", MessageType.Information, MessageSeverity.Informational);
                            System.Threading.Thread.Sleep(retry.DelayTime);
                        }

                        if (BeforeRequest != null)
                        {
                            BeforeRequest(this, new BeforeRequestEventArgs(AbstractRequest));
                        }


                        //Invoke the Service
                        DateTime start = DateTime.Now;
                        mResponse     = (AbstractResponseType)methodtype.GetMethod(apiName).Invoke(svcInst, reqparm);
                        mResponseTime = DateTime.Now - start;

                        if (AfterRequest != null)
                        {
                            AfterRequest(this, new AfterRequestEventArgs(mResponse));
                        }

                        // Catch Token Expiration warning
                        if (mResponse != null && secHdr.HardExpirationWarning != null)
                        {
                            ApiContext.ApiCredential.TokenHardExpirationWarning(
                                System.Convert.ToDateTime(secHdr.HardExpirationWarning, System.Globalization.CultureInfo.CurrentUICulture));
                        }


                        if (mResponse != null && mResponse.Errors != null && mResponse.Errors.Count > 0)
                        {
                            throw new ApiException(new ErrorTypeCollection(mResponse.Errors));
                        }
                    }

                    catch (Exception ex)
                    {
                        // this catches soap faults
                        if (ex.GetType() == typeof(TargetInvocationException))
                        {
                            // we never care about the outer exception
                            Exception iex = ex.InnerException;

                            // Parse Soap Faults
                            if (iex.GetType() == typeof(SoapException))
                            {
                                ex = ApiException.FromSoapException((SoapException)iex);
                            }
                            else if (iex.GetType() == typeof(InvalidOperationException))
                            {
                                // Go to innermost exception
                                while (iex.InnerException != null)
                                {
                                    iex = iex.InnerException;
                                }
                                ex = new ApiException(iex.Message, iex);
                            }
                            else if (iex.GetType() == typeof(HttpException))
                            {
                                HttpException httpEx = (HttpException)iex;
                                String        str    = "HTTP Error Code: " + httpEx.StatusCode;
                                ex = new ApiException(str, iex);
                            }
                            else
                            {
                                ex = new ApiException(iex.Message, iex);
                            }
                        }
                        callException = ex;

                        // log the message - override current switches - *if* (a) we wouldn't normally log it, and (b)
                        // the exception matches the exception filter.

                        if (retry != null)
                        {
                            doretry = retry.ShouldRetry(ex);
                        }

                        if (!doretry || retries == maxRetries)
                        {
                            throw ex;
                        }
                        else
                        {
                            string soapReq  = (string)this.mServiceType.GetProperty("SoapRequest").GetValue(svcInst, null);
                            string soapResp = (string)this.mServiceType.GetProperty("SoapResponse").GetValue(svcInst, null);

                            LogMessagePayload(soapReq + "\r\n\r\n" + soapResp, MessageSeverity.Informational, ex);
                            MessageSeverity svr = ((ApiException)ex).SeverityErrorCount > 0 ? MessageSeverity.Error : MessageSeverity.Warning;
                            LogMessage(ex.Message, MessageType.Exception, svr);
                        }
                    }

                    finally
                    {
                        string soapReq  = (string)this.mServiceType.GetProperty("SoapRequest").GetValue(svcInst, null);
                        string soapResp = (string)this.mServiceType.GetProperty("SoapResponse").GetValue(svcInst, null);

                        if (!doretry || retries == maxRetries)
                        {
                            LogMessagePayload(soapReq + "\r\n\r\n" + soapResp, MessageSeverity.Informational, callException);
                        }

                        if (mResponse != null && mResponse.TimestampSpecified)
                        {
                            ApiContext.CallUpdate(mResponse.Timestamp);
                        }
                        else
                        {
                            ApiContext.CallUpdate(new DateTime(0));
                        }

                        mSoapRequest  = soapReq;
                        mSoapResponse = soapResp;
                        retries++;
                    }
                } while (doretry && retries <= maxRetries);
            }

            catch (Exception ex)
            {
                ApiException aex = ex as ApiException;

                if (aex != null)
                {
                    mApiException = aex;
                }
                else
                {
                    mApiException = new ApiException(ex.Message, ex);
                }
                MessageSeverity svr = mApiException.SeverityErrorCount > 0 ? MessageSeverity.Error : MessageSeverity.Warning;
                LogMessage(mApiException.Message, MessageType.Exception, svr);

                if (mApiException.SeverityErrorCount > 0)
                {
                    throw mApiException;
                }
            }
            finally
            {
                if (this.ApiContext.EnableMetrics)
                {
                    mCallMetrics.ApiCallEnded = DateTime.Now;
                }
            }
        }