尝试使用ironpython和soap调用Web服务

时间:2012-06-19 16:02:31

标签: web-services soap wsdl ironpython

我正在尝试使用wsdl文件向网络服务器发送同步soap消息。我根据IronPython中的说明为wsdl文件创建了一个cs文件和dll以加载IronPython。我创建了我的肥皂消息(webservice要求),我认为我没有正确构建我的webRequest。

这是我的代码:

    import clr
clr.AddReference("System")
clr.AddReferenceToFileAndPath("C:\\Temp\MeetingSpaceService.dll")
clr.AddReference("System.Xml")
clr.AddReference("System.Web.Services")

from MeetingSpaceService import MeetingSpaceService
service = MeetingSpaceService()
from System.Net import WebClient
from System.IO import StreamWriter
from System.IO import StreamReader
from  System.IO import StringWriter
import System.Xml
import System.Text
from System import Uri
from System.Xml import XmlTextWriter
from System.Xml import Formatting
from System.Web.Services import *
from System.Net import HttpWebRequest
import System.Object
import System.Array
import System.Byte
from System.Xml import XmlDocument
from System.IO import File
from System.Object import ToString
#from System.ServiceModel.Description import WsdlImporter as wsdl 
from System.Web.Services.Description import (ServiceDescription,     ServiceDescriptionImporter)
from System.Web.Services.Protocols import SoapHttpClientProtocol
from System.IO import MemoryStream
from System.Net import WebClient

readerboard = ''' <?xml version="1.0" encoding="utf-8"?>
</soap:Envelope> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soap:Header>
  <wsa:Action>http://htng.org/PWSWG/2007/01/DigitalSignage#MeetingSpaceRequest</wsa:Action>
  <wsa:MessageID>urn:uuid:44088898-6926-4537-b1a3-4acc8e9f71d0</wsa:MessageID>
  <wsa:ReplyTo>
     <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
  </wsa:ReplyTo>
  <wsa:To>http://localhost:2025/MeetingSpaceProviderService/Request.asmx</wsa:To>
  <wsse:Security soap:mustUnderstand="1">
     <wsu:Timestamp wsu:Id="Timestamp-e157d58f-6589-4b3e-b2a9-5510dd9f270f">
        <wsu:Created>2011-04-17T15:35:25Z</wsu:Created>
        <wsu:Expires>2012-07-17T15:40:25Z</wsu:Expires>
     </wsu:Timestamp>"
     <wsse:UsernameToken wsu:Id="SecurityToken-843aeb4f-07de-4c78-a438-e051d3baa764">
        <wsse:Username>isacrb</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">is@cr6_662</wsse:Password>
     </wsse:UsernameToken>
  </wsse:Security>

                               “ '''

uriString = "https://ice-services.starwoodhotels.com/readerboard‏"
uri = Uri(uriString)

try: 
webRequest = HttpWebRequest.Create(uri)
webRequest.ContentType = "text/xml;charset=\"utf-8\""
webRequest.Accept = "text/xml"
webRequest.ContentLength = readerboard.Length
webRequest.Timeout = 1000000000
webRequest.Method = "POST"
webRequest.GetRequestStream()
webRequest.Write(readerboard)
webRequest.GetResponse()
except Exception, e:
    print (9) 

我在这里做了一些改变,现在这就是我得到的。 Web服务是sychnonous所以我相信正在发生的是,当您发送请求时,响应会自动返回。

  
    
      

rqt = webRequest.GetRequestStream()       在读取下一行之前有大约1.5到2.5秒的延迟。模仿SOAPUi中的行为,在发送消息之后,通常会有大约一秒钟的延迟,然后返回XML数据显示在响应框中。我想在rqt = webRequest后我需要以某种方式读取流而不要求响应。我可以发送cs文件和我创建的DLL来导入WSDL,看看你的想法。此时您应该能够访问服务器并在IDE中查看我在说什么。我感谢您的帮助。非常感谢。

    
  

以上是在上述情况之后发生的事情:

>>> rqt = webRequest.GetRequestStream()
>>> rqt.Write(byte1,0,byte1.Length)
>>>
>>>     #get the response here
>>> rsp = webRequest.GetResponse()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
SystemError: The remote server returned an error: (500) Internal Server Error.
>>>     #create a stream reader to convert the raw response into UTF8 for text
>>> readStream = StreamReader(rsp.GetResponseStream(), System.Text.Encoding.UTF8
)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'rsp' is not defined
>>>     #read the data from the stream into a string
>>> data = readStream.ReadToEnd()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'readStream' is not defined
>>> readStream.Close()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'readStream' is not defined
>>> rsp.Close()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'rsp' is not defined
>>>     #Do stuff with the data here
>>> print data
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'data' is not defined
>>>

1 个答案:

答案 0 :(得分:1)

当您发出表示SOAPAction的请求时,需要添加标头。

类似于:

webRequest.Headers.Add('SOAPAction', '"http://myservice.com/1/poll"') 

下面是调用Web服务的完整代码。在这种情况下http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL

import clr

from System.Net import WebClient
from System.IO import StreamReader
import System.Text
from System import Uri
from System.Net import HttpWebRequest

#This is the SOAP Payload 
#Just build it with basic concats
readerboard = """<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetCityWeatherByZIP xmlns="http://ws.cdyne.com/WeatherWS/">
      <ZIP>10011</ZIP>
    </GetCityWeatherByZIP>
  </soap:Body>
</soap:Envelope>"""


uriString = "http://wsf.cdyne.com/WeatherWS/Weather.asmx"
uri = Uri(uriString)

try: 
    webRequest = HttpWebRequest.Create(uri)
    webRequest.ContentType = "text/xml;charset=\"utf-8\""
    webRequest.Accept = "text/xml"
    webRequest.Timeout = 1000000000
    webRequest.Method = "POST"
    #We set the SOAPAction Header - this tells the end point what service to run
    webRequest.Headers.Add('SOAPAction', '"http://ws.cdyne.com/WeatherWS/GetCityWeatherByZIP"') 

    #we turn the payload into a byte array to allow us to write it to the request stream
    encoding = System.Text.UTF8Encoding();
    byte1 = encoding.GetBytes(readerboard);
    #write the bytes above to the request
    rqt = webRequest.GetRequestStream()
    rqt.Write(byte1,0,byte1.Length)
    #get the response here
    rsp = webRequest.GetResponse()
    #create a stream reader to convert the raw response into UTF8 for text
    readStream = StreamReader(rsp.GetResponseStream(), System.Text.Encoding.UTF8)
    #read the data from the stream into a string
    data = readStream.ReadToEnd()
    readStream.Close()
    rsp.Close()
    #Do stuff with the data here
    print data
except System.Net.WebException, we:
    print "Web Exception:", we.Message
    if we.Status == System.Net.WebExceptionStatus.ProtocolError: 
        print int(we.Response.StatusCode), we.Response.StatusDescription
        print (StreamReader(we.Response.GetResponseStream(), System.Text.Encoding.UTF8)).ReadToEnd()
except Exception, e:
    print e