public async Task <TrackResponse> TrackPackages(string trackingNumber) { TrackFieldRequest requestData = new TrackFieldRequest(trackingNumber); string Xml = requestData.ToXML(); HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, _serviceUri + Xml); HttpResponseMessage response = await _client.SendAsync(requestMessage); string responseXml = await response.Content.ReadAsStringAsync(); return(TrackResponse.LoadFromXMLString(responseXml)); }
public async Task <List <TrackInfo> > GetTrackInfoAsync(List <TrackID> input, CancellationToken cancellationToken) { // limit is 10 tracking numbers per request var requestGuid = Guid.NewGuid().ToString(); _logger.LogInformation("New request for {packageTotal} package(s). {requestGuid}", input.Count, requestGuid); List <TrackInfo> output = new(); TrackFieldRequest request; var index = 0; while (index < input.Count) { request = new TrackFieldRequest { USERID = _options.UserId, Revision = "1", ClientIp = _options.ClientIp, TrackID = input.Skip(index).Take(10).ToList(), SourceId = _options?.SourceId ?? nameof(UspsTrackingClient) }; index += 10; XmlSerializer xsSubmit = new(typeof(TrackFieldRequest)); var xml = string.Empty; using (var sww = new StringWriter()) { using var writer = XmlWriter.Create(sww); xsSubmit.Serialize(writer, request); xml = sww.ToString(); } var formData = new FormUrlEncodedContent(new[] { new KeyValuePair <string, string>("API", "TrackV2"), new KeyValuePair <string, string>("XML", xml) }); var response = await _httpClient.PostAsync(string.Empty, formData, cancellationToken).ConfigureAwait(false); var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); try { XmlSerializer deserializer = new(typeof(TrackResponse)); var ms = new MemoryStream(Encoding.UTF8.GetBytes(content)); var responseJson = (TrackResponse)deserializer.Deserialize(ms); // todo: save response data to correct input data foreach (var trackInfo in responseJson.TrackInfo) { if (trackInfo.Error != null) { _logger.LogWarning( "USPS Returned Error: {uspsErrorNumber} {uspsErrorDescription} {requestGuid}", trackInfo.Error.Number, trackInfo.Error.Description, requestGuid); } else { output.Add(trackInfo); } } } catch (Exception ex) { _logger.LogError(ex, "{requestGuid}", requestGuid); throw new UspsTrackingClientException(ex); } } return(output); }
internal static async Task <List <TrackInfo> > TrackAsync(List <TrackID> input) { // limit is 10 tracking numbers per request string requestGuid = Guid.NewGuid().ToString(); Log.Information("{area}: New request for {packageTotal} package(s). {requestGuid}", "Track()", input.Count, requestGuid); List <TrackInfo> output = new(); TrackFieldRequest request; int index = 0; while (index < input.Count) { request = new TrackFieldRequest { USERID = UspsApiUsername, Revision = "1", ClientIp = "12.174.118.186", TrackID = input.Skip(index).Take(10).ToList(), SourceId = "MYUSPS" }; index += 10; XmlSerializer xsSubmit = new(typeof(TrackFieldRequest)); var xml = ""; using (var sww = new StringWriter()) { using XmlWriter writer = XmlWriter.Create(sww); xsSubmit.Serialize(writer, request); xml = sww.ToString(); } string uspsUrl = "https://secure.shippingapis.com/ShippingAPI.dll"; var formData = new FormUrlEncodedContent(new[] { new KeyValuePair <string, string>("API", "TrackV2"), new KeyValuePair <string, string>("XML", xml) }); HttpClient httpClient = new() { Timeout = TimeSpan.FromSeconds(120) }; HttpResponseMessage response = null; int retryCount = 0; DateTime responseTimer = DateTime.Now; retry: while (response == null || response.StatusCode != System.Net.HttpStatusCode.OK) { if (retryCount > 50) { Log.Error("{area}: USPS Failed to Respond after 50 attempts. {requestGuid}", "Track()", retryCount, requestGuid); throw new UspsApiException("408: After many attempts, the request to the USPS API did not recieve a response. Please try again later."); } if (retryCount > 0) { Log.Warning("{area}: USPS Failed to Respond after " + retryCount + " seconds. Attempt {retryCount}. {requestGuid}", "Track()", retryCount, requestGuid); } try { response = await httpClient.PostAsync(uspsUrl, formData).ConfigureAwait(false); Thread.Sleep(2500 * retryCount); httpClient.CancelPendingRequests(); retryCount++; } catch { httpClient.CancelPendingRequests(); retryCount++; goto retry; } } TimeSpan responseTime = DateTime.Now.TimeOfDay.Subtract(responseTimer.TimeOfDay); var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); Log.Information("{area}: USPS response received in {responseTime} ms. {requestGuid}", "FetchRates()", responseTime.Milliseconds, requestGuid); try { XmlSerializer deserializer = new(typeof(TrackResponse)); var ms = new MemoryStream(Encoding.UTF8.GetBytes(content)); TrackResponse responseJson = (TrackResponse)deserializer.Deserialize(ms); // todo: save response data to correct input data foreach (TrackInfo trackInfo in responseJson.TrackInfo) { if (trackInfo.Error != null) { Log.Warning("{area}: USPS Returned Error: {uspsErrorNumber} {uspsErrorDescription} {requestGuid}", "Track()", trackInfo.Error.Number, trackInfo.Error.Description, requestGuid); } output.Add(trackInfo); } } catch (Exception ex) { Log.Error("{area}: Exception: {ex} {requestGuid}", "Track()", ex.ToString(), requestGuid); throw new UspsApiException(ex); } } if (output.Count != input.Count) { // something went wrong because counts should always match Console.WriteLine("Counts did not match between input and output"); throw new UspsApiException("Counts did not match between input and output"); } return(output); }