如何将php数组结构传递给soap客户端?

时间:2011-11-16 12:54:01

标签: c# serialization soap

我正在尝试使用.NET中的magento购物平台API,它并不像我想象的那么甜蜜。 事情是主要的方法有args参数,在.net生成的客户端是一个对象,并在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,遗憾的是它也没有答案。

1 个答案:

答案 0 :(得分:2)

我找到了它,希望它能帮助任何人,他们必须通过php webservices进行集成,期望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 webservices没有指定他们期望的类型(至少在我的情况下是这样),所以不要忘记将类型作为已知类型添加到客户端操作中:

        foreach (var operation in client.Endpoint.Contract.Operations)
        {
            operation.KnownTypes.Add(typeof(item));               
        }