My C# project is a class library that provides an easy to use interface to Magento 2. Consumers of the library call methods such as DownloadSalesOrder(string orderId) etc. Internally, the library has a Service Reference to a standard Magento 2 SOAP API WSDL. Visual Studio generates all the code necessary to interact with the service and deserialize the XML in the file Reference.cs. All classes in Reference.cs are declared partial.
All was working well until I discovered that one of the elements (called <extensionAttributes>) within the sales order type was customisable in Magento. For example, one API will return this:
<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>
… while another API could return a completely different structure.
The library is intended to be usable with any API, and consuming applications need this data, but obviously the library has no knowledge of the possible data types. The consuming application however would know the data type.
Could I somehow map extensionAttributes to:
- a string property, and return the inner XML as string, or
- a generically typed property, that the consuming application passes in, e.g. DownloadSalesOrder<MyExtensionAttributes>(string orderId)
All I have access to is hand editing Reference.cs and/or extending via partial classes.
I tried idea #1 by adding a string property like below, but this causes an exception: Error in deserializing body of reply message for operation ‘salesOrderRepositoryV1GetList’ (which I am not surprised by as <extensionAttributes> contains un-escaped 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");
}
}
}
Re. idea #2, I cannot make the above partial class generic, i.e. public partial class SalesDataOrderInterface<T> where T : class, because then it is no longer an extension of the original class.
2
Answers
I could not find a simple solution, but the following worked:
Consuming applications can un-wrap and deserialise the string as needed.
Try following :
Here is 2nd solution