2

I'm trying to use magento shopping platform API from .NET and it is not so sweet, as I imagined. Thing is main method has args parameter which in .net generated client is an object and in soap envelope producted by php sample looks like this:

 <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>

Problem is, that root element is array, which has some string type elements, then some key value pairs, some of those key value pairs values are arrays. How to describe object in c# to produce such hierarchy?

Update: Service reference does not describe any sructures, just interface.

[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);
    }
}

and I'm trying to call this method:

    object call(string sessionId, string resourcePath, object args);

also I found similar question here, sadly it does not have an answer also.

4
  • Use an array of objects and then put an appropriate type in each slot Commented Nov 16, 2011 at 13:01
  • could you be more concrete? because simply array of objects won't serialize i think. Also there's key and value elements, array items won't produce them. Commented Nov 16, 2011 at 13:16
  • An array of objects will serialise just fine. If you have added a web reference there should be a class for your ns2:Map type in the service namespace. Commented Nov 16, 2011 at 13:21
  • nope, it does not describe it, updated question with reference code. Commented Nov 16, 2011 at 13:35

1 Answer 1

2

I've found it, hope it will help to anybody, who will have to integrate through php webservices, that expect php arrays:

[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; }
}

Usually php webservices do not specify what kind of types they expect (at least that was in my case), so don't forget to add your type as a known type to your client operations:

        foreach (var operation in client.Endpoint.Contract.Operations)
        {
            operation.KnownTypes.Add(typeof(item));               
        }
Sign up to request clarification or add additional context in comments.

4 Comments

This looks like it is for magento Soap V1 (I know it is also a a general solution). My problem is that don't seem to be able to access the endpoint using Magento V1 client.
I think that depends on what kind of proxy is generated. If it is old Visual Studio, it may not use svcutil to generate proxy, so proxy won't have endpoint property (that is just my guess, i haven't checked if that is true). Also you're right, that is magento v1.
@Giedrius do you have an example how you now are using multiCall with the item class?
@davehay and anyone else who might be interested. Make sure you add as a service reference and not a web reference

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.