2

我在向 Walmart Marketplace API 发送批量数据交换的 POST 请求时遇到问题,希望能得到一些帮助。

背景: 我已经成功编写了签名验证例程,并且可以成功执行 GET 命令,例如获取产品等。这向我表明,验证签名的格式正确,并且标头(大部分)是正确的。

问题: 我收到 400 Bad Request 响应,请求内容无效。尝试向 Walmarts API 提交测试提要时的响应。我读过这个问题很常见,但是我还没有找到任何论坛帖子清楚地解释了实际问题,或者如何解决它。这是我当前的参数:

适用于 Chrome 的ARCA ARCA Rest 客户端

网址:

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(OK)。

我已经使用 Notepad++ XML Tools 插件验证了 XML 符合 Walmart 提供的 XSD。我看过很多关于需要应用边界的帖子,所以我还尝试更改 Content-Type 并添加边界,但未能成功接受请求。

任何帮助获得此请求以返回响应代码 200 将不胜感激。

最后,一旦此请求在 ARCA 中验证,我将在 C# 中实现。我已经编写了所有代码,但是关于如何将附件添加到 HttpWebRequest 与仅提交原始数据流之间存在一些模糊性。如果可以再次说明差异,我将不胜感激。

4

1 回答 1

0

所以这个答案并不干净和优雅,更多的是一种解决方法。我与沃尔玛工程团队中的一些人交谈过,并被告知 C# SDK 应该会在未来几个月内推出。

经过我所有的研究,您如何向沃尔玛提交多部分表格似乎有一些技巧,而且系统非常不灵活。我看过关于在 HTTP 请求正文中添加特定格式的边界的帖子,但没有这样的运气。我无法将正文作为文件或作为数据流附加到请求中。

解决方法非常简单,不幸的是丑陋。它需要一些设置,但您可以围绕 Walmart Java SDK 创建一个 .jar 包装器,并从您的 .Net 程序中调用它。

所以..过程中的步骤:

  • 获取适当的 .XSD 文件并从中生成 C# 类。
  • 构建格式正确的 XML 库存文件。确保包含命名空间!!如果您不包含适当的 ns2 / ns3 命名空间,Walmart 将失败特定调用。
  • 动态生成一个批处理文件来调用您的 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 代码,但不幸的是,文件附件的幕后发生了一些 Java 魔术,因此实际上没有任何方法可以访问 C# 的确切过程和逆向工程。我认为真正了解 Java 的人可以弄清楚,但我有足够的 Java 背景,可以让我拼凑出一个可行的,虽然丑陋的解决方案。

于 2017-07-10T17:17:39.637 回答