0

I have been trying to pass an array/list of integers from Python to C# and I keep encountering the same error:

Expecting state 'Element'.. Encountered 'Text' with name '', namespace ''. '.

This is the C# code that I am trying to pass my list of integers to:

void SimpleSetFunction(int foo, List<int> bar);

In Python, I have tried to pass it in many ways and they have all failed, returning the previously stated error. Examples of what I have tried:

client.service.SimpleSetFunction(1,[0,1,2]) #fails

client.service.SimpleSetFunction(1,['0','1','2']) #fails

The only way I was able to pass a list to SimpleSetFunction was to call the SimpleGetFunction first, and then pass the result to SimpleSetFunction.

The SimpleGetFunction would return something like this:

(ArrayOfint)
{
   int[] =
      1,
      2,
}

Which I could now pass to the Set function, like so:

foo = client.service.SimpleGetFunction()
client.service.SimpleGetFunction(1,foo) #works

The problem with such a thing, of course, is that I can only set something which is already there. I can't add any new integers to the list.

So, how do I pass the integers I want to the C# list?

Full Traceback:

Traceback (most recent call last):
  File "<path>\SimpleGet.py", l
ine 228, in <module>
    test_test()
  File "<path>\SimpleGet.py", l
ine 81, in test_test
    client.service.SimpleSetFunction(1,1)
  File "<path>\client.py"
, line 542, in __call__
    return client.invoke(args, kwargs)
  File "<path>\client.py"
, line 602, in invoke
    result = self.send(soapenv)
  File "<path>\client.py"
, line 649, in send
    result = self.failed(binding, e)
  File "<path>\client.py"
, line 702, in failed
    r, p = binding.get_fault(reply)
  File "<path>\binding.py", line 265, in get_fault
    raise WebFault(p, faultroot)

suds.WebFault: Server raised fault: 'The formatter threw an exception while tryi
ng to deserialize the message: There was an error while trying to deserialize pa
rameter http://tempuri.org/:channels. The InnerException message was 'Error in l
ine 1 position 351. Expecting state 'Element'.. Encountered 'Text'  with name ''
, namespace ''. '.  Please see InnerException for more details.'

SimpleGet.py:

import sys
import array
import time
from suds.client import Client
from array import array

def test_test():
    wsdl = 'http://*<URL>*/*<URL>*?wsdl'
    client = Client(wsdl)
    result = client.service.IsAlive()
    if result == "true":
        print "Alive"

    getResult = client.service.SimpleGetFunction(1)
    setFunction = client.service.SimpleSetFunction(1,**????**)
13
  • 1
    Are you using IronPython, or, plain python? There are multiple techniques...which one you are using isn't clear... Commented Dec 5, 2016 at 12:47
  • 1
    I think (if that's possible) that you should change parameter type from List<int> to int[] and this will work. Commented Dec 5, 2016 at 12:48
  • @deostroll I am using plain Python. I have tried using IronPython but it is throwing a ton of other errors. Commented Dec 5, 2016 at 12:52
  • @m.rogalski If I was able to change the C# code I definitely would have. Unfortunately, I am using this C# code as an API, and I do not own the original code. Commented Dec 5, 2016 at 12:54
  • 1
    Okay...it looks like you are trying to get your python program to communicate with a WCF service. The python lib you are using is "suds". The wcf is probably hosted over HTTP and the data exchange format is SOAP. The error is due to an incorrect SOAP message being generated. Please share the code for SimpleGet.py Commented Dec 5, 2016 at 17:31

1 Answer 1

1

Here is a trivial tip.

When you host a simple WCF service where one of the methods accepts some IEnumerable (i.e. typed arrays in some sense), you have to let suds consume the wsdl and create a proxy client. If you print the client you'd get some idea regarding methods you can invoke and their arguments.

from suds.client import Client
url = "<svc url>/?wsdl"
client = Client(url)
print client

This will hopefully give you an output about what you can do with the client.

enter image description here

Here my wcf service had a method called EchoNumbers which accepted an array of integers. You have to create that type in your python code for consumption.

So here is sample code for that:

from suds.client import Client

def main():
    url = "http://localhost:1308/Service1.svc?wsdl"

    client = Client(url)
    ArrayOfint = client.factory.create('ns2:ArrayOfint')
    ArrayOfint.int = [1,2,3]
    res = client.service.EchoNumbers(ArrayOfint)
    print res.string

if __name__ == '__main__':
    main()
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very very much, it helped a lot! Solved my issue. Just to understand better, how is creating the object ArrayOfInt different than creating a simply array, such as: foo = []? They are both arrays. Why is one working and the other isn't? Python treats "foo" differently?
Python list are not typed. Suds requires someway to generate the right soap envelope to issue to the wcf service and get response. Most of this is outlined by the WSDL spec.

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.