Ошибка Walmart API POST с 400 Bad Request (лента инвентаризации) ARCA

У меня проблемы с запросом POST к API Walmart Marketplace для массового обмена данными, и я надеюсь на некоторую помощь.

Предыстория: я успешно писал подпрограммы аутентификации подписи и могу успешно выполнять команды GET, такие как get products и т. Д. Это указывает на то, что подписи аутентификации правильно отформатированы, а заголовки (по большей части) верны.

Проблема: я получаю ответ 400 Неверный запрос, содержание запроса недействительно. ответ при попытке отправить тестовый фид в Walmarts API. Я читал, что эта проблема распространена, но мне еще не удалось найти ни одного сообщения на форуме, которое бы четко объясняло реальную проблему или как ее исправить. Вот мои текущие параметры:

ARCA ARCA Отдых Клиент для Chrome

URL:

https://marketplace.walmartapis.com/v2/feeds?feedType=inventory

Заголовки:

Accept: application/xml
WM_SVC.NAME: Walmart Marketplace
WM_CONSUMER.ID: <Consumer ID>
WM_SEC.AUTH_SIGNATURE: <Good Auth Signature>
WM_QOS.CORRELATION_ID: 15649814651
WM_SEC.TIMESTAMP: <Timestamp>
WM_CONSUMER.CHANNEL.TYPE: <Channel Type>
Content-Type: multipart/form-data

Вложение файла (не сырые данные, хотя это было опробовано)

<?xml version="1.0" encoding="utf-8"?>
<InventoryFeed xmlns="http://walmart.com/">
  <InventoryHeader>
    <version>1.4</version>
  </InventoryHeader>
  <inventory>
    <sku>KON04418</sku>
    <quantity>
      <unit>EACH</unit>
      <amount>4</amount>
    </quantity>
    <fulfillmentLagTime>1</fulfillmentLagTime>
  </inventory>
</InventoryFeed>

Когда я беру этот же XML-файл и проверяю его в Walmart API Explorer, файл принимается с кодом ответа 200 (ОК).

С помощью плагина Notepad++ XML Tools я подтвердил, что XML соответствует XSD, предоставленному Walmart. Я видел множество постов, касающихся границ, которые необходимо применить, поэтому я дополнительно попытался изменить тип контента и добавить границы, но безуспешно получить принятый запрос.

Любая помощь в получении этого запроса для возврата кода ответа 200 будет принята с благодарностью.

Наконец, как только этот запрос будет подтвержден в ARCA, я буду реализовывать его на C#. У меня уже есть весь написанный код, но есть некоторая неясность относительно того, как добавить вложение в HttpWebRequest вместо простой передачи потока необработанных данных. Если бы можно было дать какую-то ясность в отношении разницы, я был бы снова признателен.

1 ответ

Решение

Так что этот ответ не является чистым и элегантным, это скорее обходной путь, чем что-либо еще. Я говорил с несколькими людьми из инженерной команды Walmart, и мне сказали, что C# SDK должен появиться в ближайшие несколько месяцев.

После всех моих исследований выяснилось, что есть несколько хитростей в том, как вы отправляете многокомпонентную форму в Walmart, и система очень негибкая. Я видел сообщения о добавлении специально отформатированных границ в тело HTTP-запроса, но мне не повезло. Мне не удалось прикрепить тело в виде файла или потока данных к запросу.

Обойти это довольно просто, и, к сожалению, безобразно. Это займет немного настройки, но вы можете создать оболочку.jar вокруг Java SDK Walmart и вызывать ее из вашей программы.Net.

Итак.. шаги в процессе:

  • Соберите соответствующие файлы.XSD и сгенерируйте из них классы C#.
  • Создайте правильно отформатированный файл инвентаризации XML. Не забудьте включить пространства имен! Walmart не сможет выполнить определенные вызовы, если вы не включите соответствующие пространства имен ns2 / ns3.
  • Динамически генерируйте пакетный файл для вызова вашего Java-модуля. Появление процесса командной строки напрямую, казалось, почему-то капризно, поэтому я выбрал вместо этого командный файл.

        string path = @Directory.GetParent(Environment.CurrentDirectory).ToString();
    
        if (File.Exists(@"../inventory.bat"))
        {
            File.Delete(@"../inventory.bat");
        }
    
        string batchCommand = @"cd " + path + Environment.NewLine + @"java -jar WalmartWrapper.jar SubmitInventoryFeed inventoryFeed.xml";
        File.WriteAllText(path + @"\\inventory.bat", batchCommand);
    
        ProcessStartInfo info = new ProcessStartInfo();
        info.UseShellExecute = true;
        info.FileName = @"inventory.bat";
        info.WorkingDirectory = path;
        var p = Process.Start(info);
        p.WaitForExit();`
    
  • Отсюда, Java-модуль вступает во владение. Потребовалось немного взломать, чтобы заставить его работать больше как SDK, а не как пример программы. Вот некоторые примеры кода для работы...

  • Точка входа

    if ("SubmitInventoryFeed".equals(args[0].trim())) {
        if (args.length < 2) 
        {
            System.out.println("Need second argument for SubmitInventoryFeed");
            return;
        }
        String filename = args[1];
        Feed inventoryFeed = new Feed();
        try 
        {
            inventoryFeed.submitInventoryFeed(filename);
        } catch (Exception ex) {
            System.out.println("submitInventoryFeed failed: " + ex.getMessage());
        }
    }
    
  • Вызов SDK (это голые кости submitInventoryFeed без проверки ошибок)

    String path = Paths.get(".").toAbsolutePath().normalize().toString();
    File itemFile = FileHandler.getFile(filename.trim());
    String filePath = path + "\\" + "MarketplaceClientConfig.properties";
    WalmartMarketplace wm = Utils.getClient(filePath);
    Response response = wm.submitFeed(MarketplaceFeedType.inventory, itemFile);
    
  • Ты можешь использовать ResponseChecker.isResponse200(response, true) проверить на успешность представлений

  • Использовать FeedAcknowledgement ack = response.readEntity(FeedAcknowledgement.class); чтобы получить фактический ответ, чтобы проверить ошибки

Я буду первым, кто скажет, что мне не терпится заменить эту работу на C# SDK, ожидающий от Walmart, но на данный момент это единственный способ, которым я смог представить. Я подробно рассмотрел код walmart, но, к сожалению, под капотом происходит некое волшебство Java, которое делает вложение файлов, поэтому на самом деле нет никакого способа получить доступ к точной процедуре и обратному инжинирингу для C#. Я думаю, что кто-то, кто действительно знал Java изнутри и снаружи, мог бы понять это, но у меня достаточно опыта Java, чтобы позволить мне собрать работоспособное, хотя и некрасивое решение.

Другие вопросы по тегам