/// <summary>
        /// Implementation of raw request API
        /// </summary>
        /// <param name="cd"></param>
        /// <param name="verb"></param>
        /// <param name="relativePath"></param>
        /// <param name="jsonPayload"></param>
        /// <param name="mimeType"></param>
        /// <returns></returns>
        private async Task <HttpResponseMessage> InternalRestCallAsync(CallDuration cd, string verb, AvaTaxPath relativePath, object jsonPayload, string mimeType = null)
        {
            // Setup the request
            using (var request = new HttpRequestMessage()) {
                request.Method     = new HttpMethod(verb);
                request.RequestUri = new Uri(_envUri, relativePath.ToString());

                // Add headers
                foreach (var key in _clientHeaders.Keys)
                {
                    request.Headers.Add(key, _clientHeaders[key]);
                }

                //Add payload if present.
                if (mimeType == "multipart/form-data")
                {
                    request.Content = jsonPayload as MultipartFormDataContent;
                }
                else if (jsonPayload != null)
                {
                    request.Content = new StringContent(jsonPayload as string, Encoding.UTF8, mimeType);
                }

                // Send
                cd.FinishSetup();

                return(await _client.SendAsync(request).ConfigureAwait(false));
            }
        }
示例#2
0
        /// <summary>
        /// Implementation of raw string-returning async API
        /// </summary>
        /// <param name="cd"></param>
        /// <param name="verb"></param>
        /// <param name="relativePath"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        private async Task <string> RestCallStringAsync(string verb, AvaTaxPath relativePath, object content = null, CallDuration cd = null)
        {
            if (cd == null)
            {
                cd = new CallDuration();
            }
            using (var result = await InternalRestCallAsync(cd, verb, relativePath, content).ConfigureAwait(false)) {
                // Read the result
                var s = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                // Determine server duration
                var      sd             = result.Headers.GetValues("serverduration").FirstOrDefault();
                TimeSpan ServerDuration = new TimeSpan();
                TimeSpan.TryParse(sd, out ServerDuration);
                cd.FinishReceive(ServerDuration);

                // Deserialize the result
                if (result.IsSuccessStatusCode)
                {
                    return(s);
                }
                else
                {
                    var err = JsonConvert.DeserializeObject <ErrorResult>(s);
                    cd.FinishParse();
                    this.LastCallTime = cd;
                    throw new AvaTaxError(err);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Implementation of raw request API
        /// </summary>
        /// <param name="cd"></param>
        /// <param name="verb"></param>
        /// <param name="relativePath"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        private async Task <HttpResponseMessage> InternalRestCallAsync(CallDuration cd, string verb, AvaTaxPath relativePath, object content)
        {
            // Setup the request
            using (var request = new HttpRequestMessage()) {
                request.Method     = new HttpMethod(verb);
                request.RequestUri = new Uri(_envUri, relativePath.ToString());

                // Add credentials and client header
                if (_credentials != null)
                {
                    request.Headers.Add("Authorization", _credentials);
                }
                if (_clientHeader != null)
                {
                    request.Headers.Add("X-Avalara-Client", _clientHeader);
                }

                // Add payload
                if (content != null)
                {
                    var json = JsonConvert.SerializeObject(content, SerializerSettings);
                    request.Content = new StringContent(json, Encoding.UTF8, "application/json");
                }

                // Send
                cd.FinishSetup();
                return(await _client.SendAsync(request).ConfigureAwait(false));
            }
        }
示例#4
0
        /// <summary>
        /// Implementation of raw file-returning async API
        /// </summary>
        /// <param name="verb"></param>
        /// <param name="relativePath"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        private async Task <FileResult> RestCallFileAsync(string verb, AvaTaxPath relativePath, object content = null)
        {
            CallDuration cd = new CallDuration();

            using (var result = await InternalRestCallAsync(cd, verb, relativePath, content).ConfigureAwait(false)) {
                // Read the result
                if (result.IsSuccessStatusCode)
                {
                    var fr = new FileResult()
                    {
                        ContentType = result.Content.Headers.GetValues("Content-Type").FirstOrDefault(),
                        Filename    = GetDispositionFilename(result.Content.Headers.GetValues("Content-Disposition").FirstOrDefault()),
                        Data        = await result.Content.ReadAsByteArrayAsync().ConfigureAwait(false)
                    };
                    cd.FinishParse();
                    this.LastCallTime = cd;
                    return(fr);

                    // Handle exceptions and convert them to AvaTax results
                }
                else
                {
                    var s = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                    var err = JsonConvert.DeserializeObject <ErrorResult>(s);
                    cd.FinishParse();
                    this.LastCallTime = cd;
                    throw new AvaTaxError(err);
                }
            }
        }
示例#5
0
 /// <summary>
 /// Add another call's duration time to ours
 /// </summary>
 /// <param name="otherDuration"></param>
 public void Combine(CallDuration otherDuration)
 {
     SetupDuration   += otherDuration.SetupDuration;
     ServerDuration  += otherDuration.ServerDuration;
     TransitDuration += otherDuration.TransitDuration;
     ParseDuration   += otherDuration.ParseDuration;
 }
示例#6
0
        /// <summary>
        /// Implementation of raw string-returning async API
        /// </summary>
        /// <param name="cd"></param>
        /// <param name="verb"></param>
        /// <param name="relativePath"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        private async Task <string> RestCallStringAsync(string verb, AvaTaxPath relativePath, object content = null, CallDuration cd = null)
        {
            if (cd == null)
            {
                cd = new CallDuration();
            }
            using (var result = await InternalRestCallAsync(cd, verb, relativePath, content).ConfigureAwait(false)) {
                // Read the result
                var s = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                // Determine server duration
                var sd = DetectDuration(result, "serverduration");
                var dd = DetectDuration(result, "dataduration");
                var td = DetectDuration(result, "serviceduration");
                cd.FinishReceive(sd, dd, td);

                // Deserialize the result
                if (result.IsSuccessStatusCode)
                {
                    return(s);
                }
                else
                {
                    var err = JsonConvert.DeserializeObject <ErrorResult>(s);
                    cd.FinishParse();
                    this.LastCallTime = cd;
                    throw new AvaTaxError(err, result.StatusCode);
                }
            }
        }
        /// <summary>
        /// Implementation of raw string-returning async API
        /// </summary>
        /// <param name="cd"></param>
        /// <param name="verb"></param>
        /// <param name="relativePath"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        private async Task <string> RestCallStringAsync(string verb, AvaTaxPath relativePath, object content = null, CallDuration cd = null)
        {
            if (cd == null)
            {
                cd = new CallDuration();
            }

            // Convert the JSON payload, if any
            object jsonPayload = null;
            string mimeType    = null;

            if (content != null && content is FileResult)
            {
                var fr = (FileResult)content;
                mimeType = fr.ContentType;
                MultipartFormDataContent mpfdc            = new MultipartFormDataContent("----dataBoundary");
                ByteArrayContent         byteArrayContent = new ByteArrayContent(fr.Data);
                byteArrayContent.Headers.Add("Content-Type", "application/octet-stream");
                mpfdc.Add(byteArrayContent, fr.Filename, fr.Filename);
                jsonPayload = mpfdc;
            }
            else if (content != null)
            {
                jsonPayload = JsonConvert.SerializeObject(content, SerializerSettings);
                mimeType    = "application/json";
            }

            // Call REST
            using (var result = await InternalRestCallAsync(cd, verb, relativePath, jsonPayload, mimeType).ConfigureAwait(false)) {
                // Read the result
                var responseString = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                // Determine server duration
                var sd = DetectDuration(result, "serverduration");
                var dd = DetectDuration(result, "dataduration");
                var td = DetectDuration(result, "serviceduration");
                cd.FinishReceive(sd, dd, td);

                // Capture information about this API call and make it available for logging
                var eventargs = new AvaTaxCallEventArgs()
                {
                    HttpVerb = verb.ToUpper(), Code = result.StatusCode, RequestUri = new Uri(_envUri, relativePath.ToString()), RequestBody = jsonPayload as string, ResponseString = responseString, Duration = cd
                };
                OnCallCompleted(eventargs);

                // Deserialize the result
                if (result.IsSuccessStatusCode)
                {
                    return(responseString);
                }
                else
                {
                    var err = JsonConvert.DeserializeObject <ErrorResult>(responseString);
                    cd.FinishParse();
                    this.LastCallTime = cd;
                    throw new AvaTaxError(err, result.StatusCode);
                }
            }
        }
        /// <summary>
        /// Implementation of raw file-returning async API
        /// </summary>
        /// <param name="verb"></param>
        /// <param name="relativePath"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        private async Task <FileResult> RestCallFileAsync(string verb, AvaTaxPath relativePath, object content = null)
        {
            CallDuration cd = new CallDuration();

            // Convert the JSON payload, if any
            string jsonPayload = null;

            if (content != null)
            {
                jsonPayload = JsonConvert.SerializeObject(content, SerializerSettings);
            }

            // Call REST
            using (var result = await InternalRestCallAsync(cd, verb, relativePath, jsonPayload).ConfigureAwait(false)) {
                // Read the result
                if (result.IsSuccessStatusCode)
                {
                    var fr = new FileResult()
                    {
                        ContentType = result.Content.Headers.GetValues("Content-Type").FirstOrDefault(),
                        Filename    = GetDispositionFilename(result.Content.Headers.GetValues("Content-Disposition").FirstOrDefault()),
                        Data        = await result.Content.ReadAsByteArrayAsync().ConfigureAwait(false)
                    };

                    // Capture timings
                    cd.FinishParse();
                    this.LastCallTime = cd;

                    // Capture information about this API call and make it available for logging
                    var eventargs = new AvaTaxCallEventArgs()
                    {
                        HttpVerb = verb.ToUpper(), Code = result.StatusCode, RequestUri = new Uri(_envUri, relativePath.ToString()), RequestBody = jsonPayload, ResponseBody = fr.Data, Duration = cd
                    };
                    OnCallCompleted(eventargs);
                    return(fr);

                    // Handle exceptions and convert them to AvaTax results
                }
                else
                {
                    var errorResponseString = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                    var err = JsonConvert.DeserializeObject <ErrorResult>(errorResponseString);
                    cd.FinishParse();
                    this.LastCallTime = cd;

                    // Capture information about this API call error and make it available for logging
                    var eventargs = new AvaTaxCallEventArgs()
                    {
                        HttpVerb = verb.ToUpper(), Code = result.StatusCode, RequestUri = new Uri(_envUri, relativePath.ToString()), RequestBody = jsonPayload, ResponseString = errorResponseString, Duration = cd
                    };
                    OnCallCompleted(eventargs);
                    throw new AvaTaxError(err, result.StatusCode);
                }
            }
        }
        /// <summary>
        /// Implementation of asynchronous client APIs
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="verb"></param>
        /// <param name="relativePath"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public async Task <T> RestCallAsync <T>(string verb, AvaTaxPath relativePath, object content = null)
        {
            CallDuration cd = new CallDuration();
            var          s  = await RestCallStringAsync(verb, relativePath, content, cd).ConfigureAwait(false);

            var o = JsonConvert.DeserializeObject <T>(s);

            cd.FinishParse();
            this.LastCallTime = cd;
            return(o);
        }
        /// <summary>
        /// Implementation of raw string-returning async API
        /// </summary>
        /// <param name="cd"></param>
        /// <param name="verb"></param>
        /// <param name="relativePath"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        private async Task <string> RestCallStringAsync(string verb, AvaTaxPath relativePath, object content = null, CallDuration cd = null)
        {
            if (cd == null)
            {
                cd = new CallDuration();
            }

            // Convert the JSON payload, if any
            string jsonPayload = null;

            if (content != null)
            {
                jsonPayload = JsonConvert.SerializeObject(content, SerializerSettings);
            }

            // Call REST
            using (var result = await InternalRestCallAsync(cd, verb, relativePath, jsonPayload).ConfigureAwait(false)) {
                // Read the result
                var responseString = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                // Determine server duration
                var sd = DetectDuration(result, "serverduration");
                var dd = DetectDuration(result, "dataduration");
                var td = DetectDuration(result, "serviceduration");
                cd.FinishReceive(sd, dd, td);

                // Capture information about this API call and make it available for logging
                var eventargs = new AvaTaxCallEventArgs()
                {
                    HttpVerb = verb.ToUpper(), Code = result.StatusCode, RequestUri = new Uri(_envUri, relativePath.ToString()), RequestBody = jsonPayload, ResponseString = responseString, Duration = cd
                };
                OnCallCompleted(eventargs);

                // Deserialize the result
                if (result.IsSuccessStatusCode)
                {
                    return(responseString);
                }
                else
                {
                    var err = JsonConvert.DeserializeObject <ErrorResult>(responseString);
                    cd.FinishParse();
                    this.LastCallTime = cd;
                    throw new AvaTaxError(err, result.StatusCode);
                }
            }
        }
        /// <summary>
        /// Implementation of raw request API
        /// </summary>
        /// <param name="cd"></param>
        /// <param name="verb"></param>
        /// <param name="relativePath"></param>
        /// <param name="jsonPayload"></param>
        /// <returns></returns>
        private async Task <HttpResponseMessage> InternalRestCallAsync(CallDuration cd, string verb, AvaTaxPath relativePath, string jsonPayload)
        {
            // Setup the request
            using (var request = new HttpRequestMessage()) {
                request.Method     = new HttpMethod(verb);
                request.RequestUri = new Uri(_envUri, relativePath.ToString());

                // Add headers
                foreach (var key in _clientHeaders.Keys)
                {
                    request.Headers.Add(key, _clientHeaders[key]);
                }

                // Add payload
                if (jsonPayload != null)
                {
                    request.Content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
                }

                // Send
                cd.FinishSetup();
                return(await _client.SendAsync(request).ConfigureAwait(false));
            }
        }