c# - C# 中的 cXML PunchOutSetupRequest 和 PunchOutSetupResponse 示例

标签 c# cxml

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

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

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

我为问题(请求)的模糊性向所有人道歉。

最佳答案

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

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

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

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

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

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

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

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

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

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

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

您将使用与生成 Outbound 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,您需要将其 POST 到某个地方。您的 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,您将在控制台中看到它吐出来。如果它呕吐,您会在控制台中看到一大堆调试困惑,这当然会帮助您修复损坏的任何东西。
  • 请原谅变量名称中的冗长,这样做是为了使事情清楚。
  • 关于c# - C# 中的 cXML PunchOutSetupRequest 和 PunchOutSetupResponse 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25515578/

    相关文章:

    c# - 从 C# 运行 Bash 命令

    c# - 调试 C# 时如何找出内存中生成的项目?

    xml - 从 xsd 生成 cXML 类会引发错误 "The element ' uri :ds:Signature' is missing. "

    c# - 在 C# 中读写 cXML 文档的最佳方式是什么?

    c# - Linq 查询中的匿名类型与元组,性能注意事项

    c# - 在代码隐藏中使用资源图像

    c# - 以编程方式将 IIS 主机 header 添加到网站

    用于发票的 XML - 行业标准?

    iphone - 解析 XML iPhone 时清理 URLS(主要针对空格)