代码之家  ›  专栏  ›  技术社区  ›  brendan

使用Perl和SOAP Lite使用.NET Web服务

  •  4
  • brendan  · 技术社区  · 14 年前

    我尝试使用Perl和SOAP Lite来使用.NET Web服务。

    当我在.NET客户端中使用Web服务时,它将向.asmx端点发送以下内容:

    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:tns="http://mysoapnamespace.com/"
    xmlns:types="http://mysoapnamespace.com/encodedTypes">
      <soap:Body>
        <tns:HellowWorld  />
      </soap:Body>
    </soap:Envelope>
    

    如何使用SOAP Lite生成相同的请求?我浏览过各种各样的soap-lite文档和文章,但运气不好。到目前为止,我有以下几点:

    #!/usr/bin/perl
    use SOAP::Lite 'trace', 'debug' ;
    
    $api_ns = "https://mysoapnamespace.com";
    $api_url = "http://mysoapnamespace/api.asmx";
    $action = "HelloWorld";
    
      my $soap = SOAP::Lite 
       -> readable(1)
       -> uri($api_ns)
       -> proxy($api_url)
       -> on_action(sub { return "\"$action\"" }) ;
    
    
    return $soap->HellowWorld();
    

    这将生成不正确的XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <soap:Envelope 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
        xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <HellowWorld xmlns="http://mysoapnamespace.com" xsi:nil="true" />
          </soap:Body>
    </soap:Envelope>
    

    更新:

    当我使用fiddler将第一个XML发布到我的服务时,它将返回我的“hello world”结果。当我发布第二封邮件时,我得到以下信息:

    <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><faultcode>soap:Client</faultcode><faultstring>System.Web.Services.Protocols.SoapException: Server was unable to read request. ---&gt; System.InvalidOperationException: There is an error in XML document (9, 6). ---&gt; System.InvalidOperationException: &lt;HellowWorld xmlns='http://mysoapnamespace.com'&gt; was not expected.
       at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read21_HellowWorld()
       at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer28.Deserialize(XmlSerializationReader reader)
       at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
       --- End of inner exception stack trace ---
       at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
       at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)
       at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
       --- End of inner exception stack trace ---
       at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
       at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()</faultstring><detail /></soap:Fault></soap:Body></soap:Envelope>
    
    2 回复  |  直到 11 年前
        1
  •  4
  •   brendan    14 年前

    发现问题-命名空间上的尾随斜杠。.NET只是为您计算出这些内容,但它需要在Perl中显式设置。此外,还了解了如何使用ns()函数添加名称空间。

    这将生成正确的XML。

    #!/usr/bin/perl
    use SOAP::Lite 'trace', 'debug' ;
    
    $api_ns = "https://mysoapnamespace.com/";
    $api_url = "http://mysoapnamespace/api.asmx";
    $action = "HelloWorld";
    
      my $soap = SOAP::Lite 
       -> readable(1)
       -> ns($api_types,'types')
       -> ns($api_ns,'tns')
       -> proxy($api_url)
       -> on_action(sub { return "\"$action\"" }) ;
    
    
    return $soap->HellowWorld();
    

    这个链接对于确定soap::lite非常有用- http://kobesearch.cpan.org/htdocs/SOAP-Lite/SOAP/Lite.pm.html

        2
  •  0
  •   Stephen L. De Rudder    11 年前

    我必须做以下工作才能使它正常工作(在我的$soap后面加上这一行…线):

    $soap->ns('http://schemas.xmlsoap.org/soap/envelope/',"s");
    

    我希望这能节省一些时间…花了一段时间才弄明白…-)

    顺便说一句:我正在使用.NET 4.5 WCF和Windows Service for Web Service Server,以及Perl(ActiveState)v5.16.3和SOAP::Lite v 1.08。