问题描述
我的C#项目是一个类库,提供了易于使用的Magento 2接口。库调用方法的使用者,例如DownloadSalesOrder(string orderId)等。在内部,该库具有对标准Magento 2 SOAP的服务引用。 API WSDL。 Visual Studio生成与服务进行交互并反序列化Reference.cs文件中的XML所需的所有代码。 Reference.cs中的所有类都声明为局部的。
在我发现销售订单类型中的一个元素(称为
<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映射到:
我只能访问手工编辑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
解决方法
尝试以下操作:
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 ',';
,
我找不到简单的解决方案,但以下方法可行:
- 对于每种需要extensionAttributes属性的类型,创建一个局部类,该局部类添加具有字符串类型的属性(即,扩展Reference.cs中现有的局部类)。例如:
public partial class SalesDataOrderInterface
{
public string extensionAttributes { get; set; }
}
- 创建一个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);
}
使用中的应用程序可以根据需要解开字符串并反序列化该字符串。