亚马逊报告API - 下载的文本文件偶尔腐败

时间:2015-01-07 18:13:52

标签: c# amazon-web-services amazon-mws

我正在使用亚马逊MWS API下载包含订单的文本文件。 70%的时间文件下载完美,但有时我会腐败。如果我通过亚马逊网络前端查看该文件,它看起来很好。但是,当它存储在本地硬盘驱动器上时,它可能已损坏。我看不出为什么有些文件存在这个问题而其他文件没有模式,

我所说的腐​​败看起来像这样(数据已更改但突出显示问题)

payments-status order-id    order-item-id   payments-date   payments-transaction-id item-name   listing-id  sku price   shipping-fee    quantity-purchased  total-price purchase-date   batch-id    buyer-email buyer-name  recipient-name  ship-address-1  ship-address-2  ship-city   ship-state  ship-zip    ship-country    special-comments    upc ship-method sales-channel   VAT
    205-2599941-6954759 11274234567395  07/01/2015 15:22:48 Europe/London       My Product 1    1128h56V4X  9785858599053   3.59    2.8 1   6.39    07/01/2015 15:22:48 Europe/London       bwfdsfs3tmf15w@marketplace.amazon.co.uk Mr F Bloggs Mr Fred Bloggs  My Cottage  XXXXXXX AnyTown Isle of Man XX1 2XX GB          standard        
    205-499978-7575554  68198765457651  07/01/2015 15:28:23 Europe/London       My Product 2    1128h56MWN9 9785858524633   5.99    2.8 1   8.79    07/01/2015 15:28:23 Europe/London       zyrre44rrr7nk@marketplace.amazon.co.uk  Jane Bloggs Prof Jane Blogs Her Cottage, XXXXXXX        AnyTown Surrey  XX1 2XX GB          standard        
.99 2.8 1   8.79    07/01/2015 14:07:33 Europe/London       nuy76sz9fw4lzk@marketplace.amazon.co.uk Joe Bloggs  Joe Bloggs  71  The Houses  AnyTown MyCounty    AA1 1WW GB          standard        
    026-199993-8483529  38758765432635  07/01/2015 14:07:05 Europe/London       My Product 3 ...    118h56QMBQR 9781783610433   5.99    2.8 1   8.79    07/01/2015 14:07:05 Europe/London       h0hx8werwew4t4@marketplace.amazon.co.uk Claire Blogs    Claire Bloggs   XXXXXXX AnyTown JERSEY  Channel Islands XX1 2XX GB          standard        
    202-788880-2669961  46830987654327  07/01/2015 14:22:21 Europe/London       My Product 4    1128h56V89  978585856766    3.59    2.8 1   6.39    07/01/2015 14:22:21 Europe/London       w608ewrwewrk74l@marketplace.amazon.co.uk    Harry Blogs Harry Bloggs    XXXXXXX     AnyTown Co Durham   XX1 2XX GB          standard        
    203-355556-3369905  34856789098939  07/01/2015 14:24:42 Europe/London       My Product 5    118h56QLX1L 9785858512400   5.99    2.8 1   8.79    07/01/2015 14:24:42 Europe/London       zgw0rwewere98y@marketplace.amazon.co.uk Aimee Blogs Aimee Bloggs    XXXXXXX 25 Any Street   AnyTown     XX1 2XX GB          standard        
    204-4888812-4296349 14153456784747  07/01/2015 14:41:10 Europe/London       My Product 6    11278h5665F 9785858546360   3.59    2.8 1   6.39    07/01/2015 14:41:10 Europe/London       h5mcwerwewwwfvrg3@marketplace.amazon.co.uk  Julie Bloggs    Julie Bloggs    XXXXXXX     AnyTown Devon   XX1 2XX GB          standard        
    026-1666655-8765

这是制表符分隔文件,第一列始终为空白字段。前两行显示正确的数据,在实际文件中有很多正确的行,然后才发现这种情况。第3行从行的开头缺少多个列,最后一行缺少第二个字段的一部分以及所有其余列。

我发现这种情况主要发生在文件的末尾。

所以我使用的代码是直接来自亚马逊网站Reports C# API的库:

private T Invoke<T, K>(IDictionary<String, String> parameters, K clazz)
{

    String actionName = parameters["Action"];
    T response = default(T);
    String responseBody = null;
    HttpStatusCode statusCode = default(HttpStatusCode);
    ResponseHeaderMetadata rhm = null;

    // Verify service URL is set.
    if (String.IsNullOrEmpty(config.ServiceURL))
    {
        throw new MarketplaceWebServiceException(new ArgumentException(
            "Missing serviceUrl configuration value. You may obtain a list of valid MWS URLs by consulting the MWS Developer's Guide, or reviewing the sample code published along side this library."));      
    }

    /* Add required request parameters */
    AddRequiredParameters(parameters);

    String queryString = GetParametersAsString(parameters);
    byte[] requestData = new UTF8Encoding().GetBytes(queryString);

    HttpWebRequest request;

    bool isStreamingResponse = ExpectStreamingResponse(typeof(K));

    bool shouldRetry = true;
    int retries = 0;
    do
    {
        /* Submit the request and read response body */
        try
        {
            RequestType requestType = GetMarketplaceWebServiceRequestType(typeof(K));
            switch (requestType)
            {
                case RequestType.STREAMING:
                    {
                        SubmitFeedRequest req = clazz as SubmitFeedRequest;
                        if (req != null)
                        {
                            // SubmitFeedRequests can configure the content type.
                            request = ConfigureWebRequest(queryString, req.ContentType);
                        }
                        else
                        {
                            // Send request using a default content-type.
                            request = ConfigureWebRequest(queryString, new ContentType(MediaType.OctetStream));
                        }
                    }
                    break;
                default:
                    request = ConfigureWebRequest(requestData.Length);
                    break;
            }

            WebHeaderCollection headers = request.Headers;
            IDictionary<String, String> headerMap = GetHttpHeaderValues(clazz);
            foreach (String key in headerMap.Keys)
            {
                headers.Add(key, headerMap[key]);
            }

            using (Stream requestStream = request.GetRequestStream())
            {
                switch (requestType)
                {
                    case RequestType.STREAMING:
                        Stream inputStream = GetTransferStream(clazz, StreamType.REQUEST_STREAM);
                        inputStream.Position = 0;
                        CopyStream(inputStream, requestStream);
                        break;
                    default:
                        requestStream.Write(requestData, 0, requestData.Length);
                        break;
                }
                requestStream.Close();
            }

            using (HttpWebResponse httpResponse = request.GetResponse() as HttpWebResponse)
            {
                statusCode = httpResponse.StatusCode;
                rhm = new ResponseHeaderMetadata(
                    httpResponse.GetResponseHeader("x-mws-request-id"),
                    httpResponse.GetResponseHeader("x-mws-response-context"),
                    httpResponse.GetResponseHeader("x-mws-timestamp"));

                if (isStreamingResponse && statusCode == HttpStatusCode.OK)
                {
                    response = HandleStreamingResponse<T>(httpResponse, clazz);
                }
                else
                {

                    StreamReader reader = new StreamReader(httpResponse.GetResponseStream(), Encoding.UTF8);
                    responseBody = reader.ReadToEnd();
                    XmlSerializer serlizer = new XmlSerializer(typeof(T));
                    response = (T)serlizer.Deserialize(new StringReader(responseBody));
                }

                PropertyInfo pi = typeof(T).GetProperty("ResponseHeaderMetadata");
                pi.SetValue(response, rhm, null);

                shouldRetry = false;
            }

            /* Attempt to deserialize response into <Action> Response type */

        }
        /* Web exception is thrown on unsucessful responses */
        catch (WebException we)
        {
            shouldRetry = false;
            using (HttpWebResponse httpErrorResponse = (HttpWebResponse)we.Response as HttpWebResponse)
            {
                if (httpErrorResponse == null)
                {
                    throw new MarketplaceWebServiceException(we);
                }
                statusCode = httpErrorResponse.StatusCode;
                StreamReader reader = new StreamReader(httpErrorResponse.GetResponseStream(), Encoding.UTF8);
                responseBody = reader.ReadToEnd();
            }

            /* Attempt to deserialize response into ErrorResponse type */
            try
            {
                XmlSerializer serlizer = new XmlSerializer(typeof(ErrorResponse));
                ErrorResponse errorResponse = (ErrorResponse)serlizer.Deserialize(new StringReader(responseBody));
                Error error = errorResponse.Error[0];

                bool retriableError = (statusCode == HttpStatusCode.InternalServerError || statusCode == HttpStatusCode.ServiceUnavailable);
                retriableError = retriableError && error.Code != "RequestThrottled";

                if (retriableError && retries < config.MaxErrorRetry)
                {
                    PauseOnRetry(++retries);
                    shouldRetry = true;
                    continue;
                }
                else
                {
                    shouldRetry = false;
                }

                /* Throw formatted exception with information available from the error response */
                throw new MarketplaceWebServiceException(
                    error.Message,
                    statusCode,
                    error.Code,
                    error.Type,
                    errorResponse.RequestId,
                    errorResponse.ToXML(),
                    rhm);
            }
            /* Rethrow on deserializer error */
            catch (Exception e)
            {
                if (e is MarketplaceWebServiceException)
                {
                    throw e;
                }
                else
                {
                    MarketplaceWebServiceException se = ReportAnyErrors(responseBody, statusCode, e, rhm);
                    throw se;
                }
            }
        }

        /* Catch other exceptions, attempt to convert to formatted exception,
         * else rethrow wrapped exception */
        catch (Exception e)
        {
            throw new MarketplaceWebServiceException(e);
        }
    } while (shouldRetry);

    return response;
}

这些是传递的值:

    -       parameters  Count = 3   System.Collections.Generic.IDictionary<string,string> {System.Collections.Generic.Dictionary<string,string>}
+       [0] {[Action, GetReport]}   System.Collections.Generic.KeyValuePair<string,string>
+       [1] {[Merchant, A999AAAA7KT4OI]}    System.Collections.Generic.KeyValuePair<string,string>
+       [2] {[ReportId, 59999999994]}   System.Collections.Generic.KeyValuePair<string,string>


-       clazz   {MyCompany.MyApp.Amazon.MarketplaceWebService.Model.GetReportRequest}   MyCompany.MyApp.Amazon.MarketplaceWebService.Model.GetReportRequest
        Marketplace null    string
        marketplaceField    null    string
        Merchant    "A999AAAA7KT4OI"    string
        merchantField   "A999AAAA7KT4OI"    string
        MWSAuthToken    null    string
        mwsAuthTokenField   null    string
+       Report  {System.IO.FileStream}  System.IO.Stream {System.IO.FileStream}
+       report  {System.IO.FileStream}  System.IO.Stream {System.IO.FileStream}
        ReportId    "59999999994"   string
        reportIdField   "59999999994"   string

生成的文件保存到磁盘。

当这个问题首次出现时,我试图在寻找原因和正确修复时编写一个变通方法。这是打开文件并逐行循环,以确保每行以一个制表符开头,后跟3个数字和一个连字符,但现在由于最后一行不起作用。现在我有一点时间尝试找到为什么会发生这种情况。

我是用亚马逊提出来的,但他们说问题出在我的代码上(尽管是他们的代码)没有正确解析文件。

有人能说出为什么会发生这种情况或者指出我应该朝着哪个方向发展?

1 个答案:

答案 0 :(得分:0)

我找到了这个问题的答案。我下载的文件是Amazon.txt,每次运行都会写入。一旦我将其更改为唯一的文件名,腐败问题就会消失。