10

我正在尝试在我们的 eComm 网站上实施打孔目录。老实说,cXML 的文档是一团糟,所有的代码示例都在 javascript 和/或 VB.Net 中(我使用 C#,不想尝试翻译)。有没有人有示例或示例说明如何接收 PunchOutSetupRequest XML,然后使用 C# 发送 PunchOutSetupResponse XML?我一直无法在互联网上找到任何东西(我已经找了两天了)......

我希望我可以在 ActionResult 中执行此操作(相对于建议的“启动页面”)。

我在打孔方面完全是个菜鸟,在这里真的可以使用一些帮助。老板们都很咄咄逼人,所以任何帮助都将不胜感激。关于如何进行这项工作的建议也将不胜感激。

对于问题(请求)的含糊之处,我向所有人道歉。

4

1 回答 1

26

这不是微不足道的,但这应该让你开始。

您将需要 3 个通用处理程序 (.ashx):Setup、Start 和 Order....

Setup 和 Order 将接收内容类型为“text/xml”的 HTTP Post。如果需要将 XML 转换为字符串,请查看 HttpRequest.InputStream。从那里,查看 LINQ-to-XML 以挖掘出您想要的数据。您对这两者的 HTTP 响应也将是内容类型“text/xml”和 UTF8 编码,返回 CXML 作为记录...使用 LINQ-to-XML 来产生它。

Setup 处理程序将需要验证凭据并返回一个带有唯一 QueryString 令牌的 URL,该令牌指向 Start 处理程序。不要期望 Setup 和 Start 之间的会话持久性,因为它们不是来自同一个调用者。此处理程序将需要为您从 cXML 中提取的令牌和相关数据创建一个应用程序对象。

Start 处理程序将作为简单的 GET 调用,并且需要将 QueryString 中的令牌匹配到适当的应用程序对象,将该数据复制到会话,然后对站点中您想要的任何页面执行 response.redirect买家登陆。

一旦他们用一些东西填充他们的购物车并准备结帐,您将把他们带到一个具有嵌入式表单的页面(不要与回发到您的服务器的 ASP.Net 表单混淆)和提交按钮(同样,不是 ASP.Net 按钮)。从您的 Setup 处理程序中,您捕获了一个指向此表单的 Post 的 URL,并且在表单中您将拥有一个隐藏的输入标记,其中 UTF8 编码的 CXML Punchout Order 作为使用 LINQ-to-XML 生成的值注入。强烈建议对该值进行 Base64 编码,以避免 ASP.Net 在渲染期间弄乱它包含的标签,并根据文档将隐藏的输入命名为“cxml-base64”。结果是表单被客户端发布到您客户的服务器而不是您的服务器,他们的服务器将提取 CXML Punchout Order 并结束您的访问者的会话。

Order 处理程序将接收 CXML OrderRequest,就像安装程序一样,您将把它转储到一个字符串中,然后使用 LINQ-to-XML 来解析它并对其采取行动。同样,您将获得用于验证的凭据,可能是要处理的信用卡,以及订单商品、收货人等。请注意,OrderRequest 可能不包含 Punchout Order 中的所有商品,因为您客户的系统上的系统在向您提交最终 OrderRequest 之前,side 可能会删除项目甚至更改项目数量。在将 Punchout 订单发布给他们后,OrderRequest 可能会在几分钟、几天、几周内或永远不会返回给您……不要费心存储购物车数据以希望稍后将其与订单匹配。

最后一点...买家可能会在嵌入在其基于 Web 的采购 UI 中的 iframe 中体验您的网站,因此请相应地进行设计。

如果您需要更多信息,请回复此内容,我会回复您。

更新...其他注意事项:与买家讨论他们希望如何处理故障,尤其是订单,因为您有选择权。1) 详尽评估您收到的 CXML 中的所有内容,如果有任何错误,则返回 200 以外的响应代码,或者 2) 始终返回 200 Success 并处理带外的任何问题,或者生成拒绝订单的 ConfirmationRequest。我的经验是两者混合效果最好。当然,如果凭据失败,您应该抛出非 200,但您可能不希望(或能够)运行信用卡或在线验证库存可用性。您的买方系统可能无法处理数十种可能的故障,和/或可能无法向用户显示您的故障信息,以便他们进行更正。一世' 已经看到系统会彻底丢弃任何非 200 响应代码,只是盲目地每隔数小时或数天反复重试提交,直到它放弃完整性检查,而其他系统会以与其他方式不同的方式处理特定范围内的响应代码,例如 4xx 调用重试,而 5xx 被视为致命。请记住,设置和订单不是直接来自用户……他们的采购系统是在内部生成的。


更新...回答有关如何测试事物的评论...

您将使用与生成出站 ConfirmationRequest、ShipNoticeRequest 和 InvoiceDetailRequest 相同的方法,所有这些通常都是在您从客户的采购系统收到 OrderRequest 后在您身边生成的。

从Linq-To-XML开始,了解制作传出 cXML 的示例(创建 XML 树部分)。将该示例与这段代码结合起来:

StringBuilder output = new StringBuilder();

XmlWriterSettings objXmlWriterSettings = new XmlWriterSettings();
objXmlWriterSettings.Indent = true;
objXmlWriterSettings.NewLineChars = Environment.NewLine;
objXmlWriterSettings.NewLineHandling = NewLineHandling.Replace;
objXmlWriterSettings.NewLineOnAttributes = false;
objXmlWriterSettings.Encoding = new UTF8Encoding();

using (XmlWriter objXmlWriter = XmlWriter.Create(output, objXmlWriterSettings)) {
    XElement root = new XElement("Root",
        new XElement("Child", "child content")
    );
    root.Save(objXmlWriter);
}
Console.WriteLine(output.ToString());

所以此时 StringBuilder(输出)有你的整个 cXML,你需要在某个地方发布它。您的 Web 应用程序项目,从 F5 开始,一个 default.aspx 页面将监听 localhost 和一些端口(您将在它打开的 URL 中看到)。另外,也许使用 VS Express for Desktop,您在控制台应用程序中拥有上述代码,您可以使用以下代码运行该代码来执行 Post:

Net.HttpWebRequest objRequest = Net.WebRequest.Create("http://localhost:12345/handler.ashx");

objRequest.Method = "POST";
objRequest.UserAgent = "Some User Agent";
objRequest.ContentLength = output.Length;
objRequest.ContentType = "text/xml";

IO.StreamWriter objStreamWriter = new IO.StreamWriter(objRequest.GetRequestStream, System.Text.Encoding.ASCII);
objStreamWriter.Write(output);
objStreamWriter.Flush();
objStreamWriter.Close();

Net.WebResponse objWebResponse = objRequest.GetResponse();
XmlReaderSettings objXmlReaderSettings = new XmlReaderSettings();
objXmlReaderSettings.DtdProcessing = DtdProcessing.Ignore;
XmlReader objXmlReader = XmlReader.Create(objWebResponse.GetResponseStream, objXmlReaderSettings);

// Pipes the stream to a higher level stream reader with the required encoding format.  
IO.MemoryStream objMemoryStream2 = new IO.MemoryStream();
XmlWriter objXmlWriter2 = XmlWriter.Create(objMemoryStream2, objXmlWriterSettings);
objXmlWriter2.WriteNode(objXmlReader, true);
objXmlWriter2.Flush();
objXmlWriter2.Close();
objWebResponse.Close();

// Reset current position to the beginning so we can read all below.
objMemoryStream2.Position = 0;

StreamReader objStreamReader = new StreamReader(objMemoryStream2, Encoding.UTF8);
Console.WriteLine(objStreamReader.ReadToEnd());
objStreamReader.Close();

由于您的处理程序应该生成 cXML,您会在控制台中看到它吐出的内容。如果它呕吐,你会在控制台中得到一大堆调试混乱,这当然会帮助你修复任何被破坏的东西。

  • 请原谅变量名称中的冗长,这样做是为了让事情变得清晰。
于 2014-08-30T14:39:33.243 回答