tags:

views:

104

answers:

4

Hi. I am consuming a web service from a third party site. I have the type and method in the wsdl file called GetItemAvailable. When i consume and execute the service it returns a SOAP array (defined in the wsdl as ItemsArray). The porblem is, i'm not sure what type i need to use to get to the information. here is my code:

GetItemAvailable.GetItemAvailable gia = new GetItemAvailable.GetItemAvailable();
ItemsArray ia = new ItemsArray();
ia = (gia.CallGetItemAvailable("1088507721", "9780842387491"));
string sttest = ia.id[1].ToString();

The error always says that ia.id is null

what am i doing wrong? i'm not very familiar with SOAP. Here is the wsdl:

<wsdl:definitions>
  <wsdl:types>
    <xsd:complexType name="Items">
        <xsd:all>
          <xsd:element name="item_id" type="xsd:string" />
          <xsd:element name="tn_onhand" type="xsd:int" />
          <xsd:element name="tn_onorder" type="xsd:string" />
          <xsd:element name="tn_onorder_eta" type="xsd:string" />
          <xsd:element name="nv_onhand" type="xsd:int" />
          <xsd:element name="nv_onorder" type="xsd:string" />
          <xsd:element name="nv_onorder_eta" type="xsd:string" />
          <xsd:element name="error" type="xsd:string" />
        </xsd:all>
      </xsd:complexType>
      <xsd:complexType name="ItemsArray">
        <xsd:complexContent mixed="false">
          <xsd:restriction base="SOAP-ENC:Array">
            <xsd:attribute wsdl:arrayType="tns:Items[]" ref="SOAP-ENC:arrayType" />
          </xsd:restriction>
        </xsd:complexContent>
      </xsd:complexType>
      <xsd:complexType name="GetItemAvailableRequestType">
        <xsd:all>
          <xsd:element name="api_key" type="xsd:string" />
          <xsd:element name="Items" type="xsd:string" />
        </xsd:all>
      </xsd:complexType>
      <xsd:complexType name="GetItemAvailableResponseType">
        <xsd:all>
          <xsd:element name="GetItemAvailableResult" type="tns:ItemsArray" />
        </xsd:all>
      </xsd:complexType>
      <xsd:element name="GetItemAvailable" type="tns:GetItemAvailableRequestType" />
      <xsd:element name="GetItemAvailableResponse" type="tns:GetItemAvailableResponseType" />
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="GetItemAvailableRequest">
    <wsdl:part name="parameters" element="tns:GetItemAvailable" />
  </wsdl:message>
  <wsdl:message name="GetItemAvailableResponse">
    <wsdl:part name="parameters" element="tns:GetItemAvailableResponse" />
  </wsdl:message>
  <wsdl:portType name="GetItemAvailablePortType">
    <wsdl:operation name="GetItemAvailable">
      <documentation>Returns quantity available and on order for list of products seperated by comma (example: 9780877840756,9780446691093)</documentation>
      <wsdl:input message="tns:GetItemAvailableRequest" />
      <wsdl:output message="tns:GetItemAvailableResponse" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="GetItemAvailableBinding" type="tns:GetItemAvailablePortType">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="GetItemAvailable">
      <soap:operation soapAction="http://www.stl-distribution.com/GetItemAvailable" style="document" />
      <wsdl:input>
        <soap:body use="literal" namespace="http://www.stl-distribution.com" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" namespace="http://www.stl-distribution.com" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="GetItemAvailable">
    <wsdl:port name="GetItemAvailablePort" binding="tns:GetItemAvailableBinding">
      <soap:address location="http://www.stl-distribution.com/webservices/soap/GetItemAvailable.php" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
+4  A: 

Shouldn't that be

//string sttest = ia.id[1].ToString();
string sttest = ia[0].item_id;
Henk Holterman
That's what i would think too. but i get the folling message. Cannot apply indexing with [] to an expression of type GetItemAvaialable.IemArray. i guess that means its not really an array, so im not sure how to read it in
Tim
Maybe it's ia.Items[0], look around in the generated .cs or with Intellisense.
Henk Holterman
that's what i don't understand. there is is no generated .cs the app_webreferences folder just has the .disco and .wsdl. do i need to try and run the wsld.exe tool? i am using another web service from the same company in the same way that just returns one string instead of an array and it works fine.
Tim
@Tim, put the cursor on `ia` and hit [F12]
Henk Holterman
takes me to this namespace GetItemAvailable{ [Serializable] [GeneratedCode("System.Xml", "2.0.50727.3082")] [DebuggerStepThrough] [DesignerCategory("code")] [XmlType(Namespace = "http://www.stl-distribution.com")] public class ItemsArray : Array { public ItemsArray(); } }
Tim
i must have looked at a thousand pages now trying to figure this out. could it be that the following code is giving some interopability issues:<xsd:complexType name="ItemsArray"> <xsd:complexContent mixed="false"> <xsd:restriction base="SOAP-ENC:Array"> <xsd:attribute wsdl:arrayType="tns:Items[]" ref="SOAP-ENC:arrayType" /> </xsd:restriction> </xsd:complexContent> </xsd:complexType>
Tim
@Tim, go back to the question and list all relevabt details (.Net and Vs versions, what language/tool does the other side use). And maybe try this in a WinForms project, makes finding the generated code easier.
Henk Holterman
But mostly, you can type `ia.` and look at the intellisense. And/or try `ia[0].`
Henk Holterman
Henk, i really appricate you doing this. I'm using VS2008 c# .net framework 2 (3.5). i believe the the webservice was written in SOAP PHP5. When i run the program in debug and mouse over ItemsArray I get this: When I run it in debug, and then mouse over ItemsArray it says: -ItemsArray|GetItemAvailable.ItemsArray -base{GetItemAvailable.Array} GetItemAvailable.Array -base{object} object ia. returns the following properties any anyattr arraytype equals gethascode,gettype,hrif,id,offset, and tostring
Tim
Tim, make a WinForms proj and add it as a _service_ ref (not a web ref).
Henk Holterman
+1  A: 

What Henk says make sense.

Also, is this compiling for you. Based on the wsdl below:

<xsd:complexType name="Items"> 
        <xsd:all> 
          <xsd:element name="item_id" type="xsd:string" /> 
          <xsd:element name="tn_onhand" type="xsd:int" /> 
          <xsd:element name="tn_onorder" type="xsd:string" /> 
          <xsd:element name="tn_onorder_eta" type="xsd:string" /> 
          <xsd:element name="nv_onhand" type="xsd:int" /> 
          <xsd:element name="nv_onorder" type="xsd:string" /> 
          <xsd:element name="nv_onorder_eta" type="xsd:string" /> 
          <xsd:element name="error" type="xsd:string" /> 
        </xsd:all> 
</xsd:complexType>

I would expect ia[x].item_id - and this value should be string already.

So maybe your code should look like:

GetItemAvailable.GetItemAvailable gia = new GetItemAvailable.GetItemAvailable();      
ItemsArray ia = new ItemsArray();      
ia = (gia.CallGetItemAvailable("1088507721", "9780842387491"));      
string sttest = ia[0].item_id;
Wagner Silveira
Sorry Henk, I didn't see that you've had it as item_id when I was posting my answer.
Wagner Silveira
@Wagner: I edited that later.
Henk Holterman
The code does compile. i get Cannot apply indexing with [] to an expression of type GetItemAvaialable.IemArray
Tim
A: 

Hi guys,

This might or not help, but it is worth a try. Looking at the wsdl again:

<xsd:complexType name="GetItemAvailableResponseType">
  <xsd:all> 
    <xsd:element name="GetItemAvailableResult" type="tns:ItemsArray" /> 
  </xsd:all> 
</xsd:complexType>

Seems like the Response have an object GetItemsAvailableResult that is actually f type ItemsArray.

Did you try ia.GetItemsAvailableResult[0].item_id yet?

Hopefully this will help. BTW, I added as another answer, because it would be too messy to add the code snippet within the comments.

Cheers, Wagner.

Wagner Silveira
+1  A: 

I got the issue resolved by writting a new class to wrap around the WSDL file. Guess i should have just done this in the first place. Thanks for all the help guys!!!

 public class STLItemAvailable
    {
        private string _itemNumber;
        public string ItemNumber
        {
            get
            {
                return _itemNumber;
            }
        }

        private int _tnOnHand;
        public int TNOnHand
        {
            get
            {
                return _tnOnHand;
            }
        }

        private int _tnOnOrder;
        public int TNOnOrder
        {
            get
            {
                return _tnOnOrder;
            }
        }

        private DateTime _tnOrderETA;
        public DateTime TNOrderETA
        {
            get
            {
                return _tnOrderETA;
            }
        }

        private int _nvOnHand;
        public int NVOnHand
        {
            get
            {
                return _nvOnHand;
            }
        }

        private int _nvOnOrder;
        public int NVOnOrder
        {
            get
            {
                return _nvOnOrder;
            }
        }

        private DateTime _nvOrderETA;
        public DateTime NVOrderETA
        {
            get
            {
                return _nvOrderETA;
            }
        }

        public STLItemAvailable()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        public STLItemAvailable(string APIKey, string ItemNumber)
        {
            GetItemAvailable gia = new GetItemAvailable();
            ItemsArray ia = gia.CallGetItemAvailable(APIKey, ItemNumber);

            XmlElement[] XEArray = ia.Any;
            XmlNode n = XEArray[0];

            int testn = 0;
            DateTime testd;
            foreach (XmlNode xn in n.ChildNodes)
            {
                switch (xn.Name)
                {
                    case "item_id":
                        this._itemNumber = xn.InnerText;
                        break;
                    case "tn_onhand":
                        int.TryParse(xn.InnerText, out testn);
                        this._tnOnHand = testn;
                        break;
                    case "tn_onorder":
                        int.TryParse(xn.InnerText, out testn);
                        this._tnOnOrder = testn;
                        break;
                    case "tn_onorder_eta":
                        DateTime.TryParse(xn.InnerText, out testd);
                        this._tnOrderETA = testd;
                        break;
                    case "nv_onhand":
                        int.TryParse(xn.InnerText, out testn);
                        this._nvOnHand = testn;
                        break;
                    case "nv_onorder":
                        int.TryParse(xn.InnerText, out testn);
                        this._nvOnOrder = testn;
                        break;
                    case "nv_onorder_eta":
                        DateTime.TryParse(xn.InnerText, out testd);
                        this._nvOrderETA = testd;
                        break;
Tim