如何将php数组结构传递给soap客户端?
问题描述:
我试图从.NET使用magento购物平台API,并不像我想象的那么甜。 事情是主要方法有args参数这在.NET生成的客户端是由PHP样品开发生产的对象,在SOAP信封看起来像这样:如何将php数组结构传递给soap客户端?
<args SOAP-ENC:arrayType="xsd:ur-type[4]" xsi:type="SOAP-ENC:Array">
<item xsi:type="xsd:string">simple</item>
<item xsi:type="xsd:int">4</item>
<item xsi:type="xsd:string">sku_of_product</item>
<item xsi:type="ns2:Map">
<item>
<key xsi:type="xsd:string">name</key>
<value xsi:type="xsd:string">name of product</value>
</item>
<item>
<key xsi:type="xsd:string">short_description</key>
<value xsi:type="xsd:string">short description</value>
</item>
<item>
<key xsi:type="xsd:string">description</key>
<value xsi:type="xsd:string">description</value>
</item>
<item>
<key xsi:type="xsd:string">status</key>
<value xsi:type="xsd:int">1</value>
</item>
<item>
<key xsi:type="xsd:string">weight</key>
<value xsi:type="xsd:int">0</value>
</item>
<item>
<key xsi:type="xsd:string">tax_class_id</key>
<value xsi:type="xsd:int">1</value>
</item>
<item>
<key xsi:type="xsd:string">categories</key>
<value SOAP-ENC:arrayType="xsd:int[1]" xsi:type="SOAP-ENC:Array">
<item xsi:type="xsd:int">3</item>
</value>
</item>
<item>
<key xsi:type="xsd:string">price</key>
<value xsi:type="xsd:float">12.05</value>
</item>
</item>
</args>
问题是,根元素是阵列,其中有一些字符串类型元素,然后是一些关键值对,其中一些关键值对是数组。 如何在c#中描述对象来产生这样的层次结构?
更新:服务引用没有描述任何状态结构,只是接口。
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="urn:Magento", ConfigurationName="EpcServiceReference.Mage_Api_Model_Server_HandlerPortType")]
public interface Mage_Api_Model_Server_HandlerPortType {
[System.ServiceModel.OperationContractAttribute(Action="urn:Mage_Api_Model_Server_HandlerAction", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, SupportFaults=true, Use=System.ServiceModel.OperationFormatUse.Encoded)]
[return: System.ServiceModel.MessageParameterAttribute(Name="callReturn")]
object call(string sessionId, string resourcePath, object args);
[System.ServiceModel.OperationContractAttribute(Action="urn:Mage_Api_Model_Server_HandlerAction", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, SupportFaults=true, Use=System.ServiceModel.OperationFormatUse.Encoded)]
[return: System.ServiceModel.MessageParameterAttribute(Name="multiCallReturn")]
object[] multiCall(string sessionId, object[] calls, object options);
[System.ServiceModel.OperationContractAttribute(Action="urn:Mage_Api_Model_Server_HandlerAction", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, SupportFaults=true, Use=System.ServiceModel.OperationFormatUse.Encoded)]
[return: System.ServiceModel.MessageParameterAttribute(Name="endSessionReturn")]
bool endSession(string sessionId);
[System.ServiceModel.OperationContractAttribute(Action="urn:Mage_Api_Model_Server_HandlerAction", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, SupportFaults=true, Use=System.ServiceModel.OperationFormatUse.Encoded)]
[return: System.ServiceModel.MessageParameterAttribute(Name="loginReturn")]
string login(string username, string apiKey);
[System.ServiceModel.OperationContractAttribute(Action="urn:Mage_Api_Model_Server_HandlerAction", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, SupportFaults=true, Use=System.ServiceModel.OperationFormatUse.Encoded)]
[return: System.ServiceModel.MessageParameterAttribute(Name="startSessionReturn")]
string startSession();
[System.ServiceModel.OperationContractAttribute(Action="urn:Mage_Api_Model_Server_HandlerAction", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, SupportFaults=true, Use=System.ServiceModel.OperationFormatUse.Encoded)]
[return: System.ServiceModel.MessageParameterAttribute(Name="resourcesReturn")]
object[] resources(string sessionId);
[System.ServiceModel.OperationContractAttribute(Action="urn:Mage_Api_Model_Server_HandlerAction", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, SupportFaults=true, Use=System.ServiceModel.OperationFormatUse.Encoded)]
[return: System.ServiceModel.MessageParameterAttribute(Name="globalFaultsReturn")]
object[] globalFaults(string sessionId);
[System.ServiceModel.OperationContractAttribute(Action="urn:Mage_Api_Model_Server_HandlerAction", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style=System.ServiceModel.OperationFormatStyle.Rpc, SupportFaults=true, Use=System.ServiceModel.OperationFormatUse.Encoded)]
[return: System.ServiceModel.MessageParameterAttribute(Name="resourceFaultsReturn")]
object[] resourceFaults(string resourceName, string sessionId);
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface Mage_Api_Model_Server_HandlerPortTypeChannel : MagentoTest.EpcServiceReference.Mage_Api_Model_Server_HandlerPortType, System.ServiceModel.IClientChannel {
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class Mage_Api_Model_Server_HandlerPortTypeClient : System.ServiceModel.ClientBase<MagentoTest.EpcServiceReference.Mage_Api_Model_Server_HandlerPortType>, MagentoTest.EpcServiceReference.Mage_Api_Model_Server_HandlerPortType {
public Mage_Api_Model_Server_HandlerPortTypeClient() {
}
public Mage_Api_Model_Server_HandlerPortTypeClient(string endpointConfigurationName) :
base(endpointConfigurationName) {
}
public Mage_Api_Model_Server_HandlerPortTypeClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public Mage_Api_Model_Server_HandlerPortTypeClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public Mage_Api_Model_Server_HandlerPortTypeClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}
public object call(string sessionId, string resourcePath, object args) {
return base.Channel.call(sessionId, resourcePath, args);
}
public object[] multiCall(string sessionId, object[] calls, object options) {
return base.Channel.multiCall(sessionId, calls, options);
}
public bool endSession(string sessionId) {
return base.Channel.endSession(sessionId);
}
public string login(string username, string apiKey) {
return base.Channel.login(username, apiKey);
}
public string startSession() {
return base.Channel.startSession();
}
public object[] resources(string sessionId) {
return base.Channel.resources(sessionId);
}
public object[] globalFaults(string sessionId) {
return base.Channel.globalFaults(sessionId);
}
public object[] resourceFaults(string resourceName, string sessionId) {
return base.Channel.resourceFaults(resourceName, sessionId);
}
}
,我试图调用此方法:
object call(string sessionId, string resourcePath, object args);
还我发现类似的问题here,遗憾的是它没有一个答案也。
答
我已经找到了,希望这将有助于任何人,谁必须通过PHP的Web服务,即希望PHP阵列整合:
[SoapType(TypeName = "Map", Namespace = "http://xml.apache.org/xml-soap")]
public class item
{
[XmlElement(Form = XmlSchemaForm.Unqualified)]
public string key { get; set; }
[XmlElement(Form = XmlSchemaForm.Unqualified)]
public string value { get; set; }
[XmlArray("item")]
[XmlArrayItem(typeof(item), ElementName = "item")]
public item[] items { get; set; }
}
通常是PHP Web服务不指定他们希望什么样的类型(那是在我的情况最少),所以不要忘了作为已知类型添加类型到你的客户端操作:
foreach (var operation in client.Endpoint.Contract.Operations)
{
operation.KnownTypes.Add(typeof(item));
}
使用对象的数组,然后把合适的类型,每个插槽 –
可能你更具体一些?因为简单的对象数组将不会序列化我认为。还有关键和价值元素,数组项不会产生它们。 – Giedrius
一个对象数组会很好地串行化。如果您添加了Web引用,则应在服务名称空间中为您的ns2:Map类型提供一个类。 –