微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将XML反序列化为已知类型,其中一个元素的结构可变在SOAP Service Reference中

如何解决将XML反序列化为已知类型,其中一个元素的结构可变在SOAP Service Reference中

我的C#项目是一个类库,提供了易于使用的Magento 2接口。库调用方法的使用者,例如DownloadSalesOrder(string orderId)等。在内部,该库具有对标准Magento 2 SOAP的服务引用。 API WSDL。 Visual Studio生成与服务进行交互并反序列化Reference.cs文件中的XML所需的所有代码。 Reference.cs中的所有类都声明为局部的。

在我发现销售订单类型中的一个元素(称为)可以在Magento中进行自定义之前,一切工作正常。例如,一个API将返回以下内容

            <extensionAttributes>
              <paymentAdditionalInfo>
                <item>
                  <key>processorResponseText</key>
                  <value>Approved</value>
                </item>
                <item>
                  <key>cc_type</key>
                  <value>Visa</value>
                </item>
              </paymentAdditionalInfo>
              <giftCards>
                <item>
                  <id>14</id>
                  <code>0BVH6GOQ291C</code>
                  <amount>20</amount>
                  <baseAmount>20</baseAmount>
                </item>
              </giftCards>
            </extensionAttributes>

...而另一个API可能返回完全不同的结构。

该库旨在与任何API一起使用,并且使用中的应用程序需要此数据,但是显然,该库不知道可能的数据类型。但是,使用中的应用程序会知道数据类型。

我能以某种方式将extensionAttributes映射到:

  1. 字符串属性,然后将内部XML作为字符串返回,或者
  2. 消费应用程序传入的
  3. 通用类型的属性,例如DownloadSalesOrder (字符串orderId)

我只能访问手工编辑Reference.cs和/或通过局部类进行扩展。

我尝试通过添加如下所示的字符串属性来尝试方法#1,但这会导致异常:反序列化操作'salesOrderRepositoryV1GetList'的答复消息正文时发生错误(对于包含未转义的XML)。


    public partial class SalesDataOrderInterface
    {
        private string extensionAttributesField;

        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified,Order=136)]
        public string extensionAttributes
        {
            get {
                return this.extensionAttributesField;
            }
            set {
                this.extensionAttributesField = value;
                this.RaisePropertyChanged("extensionAttributes");
            }
        }
    }

重新。想法#2,我无法使上述部分类通用,即,公共部分类SalesDataOrderInterface 其中T:类,因为那样,它不再是原始类的扩展。

解决方法

尝试以下操作:

UNLOAD ('select * from inputTable') TO 's3://bucket/key/unload_' manifest allowoverwrite ADDQUOTES ESCAPE DELIMITER ',';

这是第二种解决方法

COPY targetTable FROM 's3://bucket/key/unload_manifest' manifest REMOVEQUOTES ESCAPE DELIMITER ',';
,

我找不到简单的解决方案,但以下方法可行:

  1. 对于每种需要extensionAttributes属性的类型,创建一个局部类,该局部类添加具有字符串类型的属性(即,扩展Reference.cs中现有的局部类)。例如:
    public partial class SalesDataOrderInterface
    {
        public string extensionAttributes { get; set; }
    }
  1. 创建一个WCF消息检查器,该检查器将拦截传入的XML并将其重写,查找任何元素并通过将内部XML封装在CDATA块中来转义内部XML。因此,所有元素都映射到上面创建的字符串属性。这是检查员的相关方法:
        public void AfterReceiveReply(ref Message reply,object correlationState)
        {
            // Read reply XML 
            var replyAsXml = new XmlDocument();
            var ms = new MemoryStream();
            var writer = XmlWriter.Create(ms);
            reply.WriteMessage(writer);
            writer.Flush();
            ms.Position = 0;
            replyAsXml.Load(ms);

            // Find any <extensionAttributes> elements and escape the XML so it can be deserialised as a single string property
            // The contents of <extensionAttributes> are customisable in Magento,so we cannot know the type they map to
            foreach (XmlNode extensionAttributesElement in replyAsXml.GetElementsByTagName("extensionAttributes"))
            {
                var elementXml = extensionAttributesElement.OuterXml;
                foreach (XmlNode childNode in extensionAttributesElement.ChildNodes)
                    extensionAttributesElement.RemoveChild(childNode);

                extensionAttributesElement.InnerText = string.Format("<![CDATA[{0}]]>",elementXml);
            }

            // Create the modified reply
            ms.SetLength(0);
            writer = XmlWriter.Create(ms);
            replyAsXml.WriteTo(writer);
            writer.Flush();
            ms.Position = 0;
            var reader = XmlReader.Create(ms);
            reply = Message.CreateMessage(reader,int.MaxValue,reply.Version);
        }

使用中的应用程序可以根据需要解开字符串并反序列化该字符串。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。