c# - 沃尔玛 API POST 因 400 错误请求(库存提要)ARCA 而失败

标签 c# rest http http-status-code-400 walmart-api

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

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

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

阿卡 ARCA Rest Client For Chrome

网址:

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 工具插件验证 XML 符合沃尔玛提供的 XSD。我看过很多关于需要应用边界的帖子,所以我还尝试更改内容类型并添加边界,但未能成功接受请求。

如果您能帮助我们获得返回响应代码 200 的请求,我们将不胜感激。

最后,一旦此请求在 ARCA 中得到验证,我将在 C# 中实现。我已经编写了所有代码,但是对于如何向 HttpWebRequest 添加附件与仅提交原始数据流相比,我有些模糊。如果可以就差异提供任何说明,我会再次表示感谢。

最佳答案

所以这个答案不是干净和优雅的,更多的是变通。我与沃尔玛工程团队内部的一些人进行了交谈,并被告知 C# SDK 应该会在接下来的几个月内推出。

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

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

所以..过程中的步骤:

  • 获取适当的 .XSD 文件并从中生成 C# 类。
  • 构建格式正确的 XML list 文件。确保包含命名空间!!如果您不包含适当的 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);获取实际响应以检查错误

我会第一个说我迫不及待地想用 Walmart 待定的 C# SDK 替换这项工作,但目前,这是我能够提交的唯一方式。我已经深入查看了 walmart 代码,但不幸的是,在文件附件的幕后发生了一些 Java 魔术,因此实际上没有任何方法可以访问 C# 的确切过程和逆向工程。我认为真正了解 Java 内外的人可以解决这个问题,但我有足够的 Java 背景,可以拼凑出一个可行的解决方案,尽管它很丑陋。

关于c# - 沃尔玛 API POST 因 400 错误请求(库存提要)ARCA 而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43282583/

相关文章:

javascript - JSON、AJAX 和 ASP.NET

c# - 具有有序输入和输出的并行管道

c# - 如何使用格式剪切、复制和粘贴?

java - JSON 中 RestTemplate 中的 GET 请求

c# - 如何使用AutoFixture实现日期限制?

json - MVVM 的异步 JSON REST 调用问题

mysql - laravel REST api post 方法

ruby-on-rails - 更改 Rails 中的 HTTP header

api - 对于业务规则失败,Web API 应该返回什么 http 状态代码?

http - 我是否也应该在单页应用程序中的 ajax 响应中设置内容安全策略 header ?