qiezi的学习园地

AS/C/C++/D/Java/JS/Python/Ruby

  C++博客 :: 首页 :: 新随笔 ::  ::  :: 管理 ::
首先写一个简单的webservice:

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService(Namespace 
= "http://tempuri.org/")]
[WebServiceBinding(ConformsTo 
= WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
    [WebMethod]
    
public string HelloWorld(string name) {
        
return "Hello, " + name;
    }
    
}

在RoR项目里,添加app/apis/test_api.rb:

class TestApi < ActionWebService::API::Base
  api_method :HelloWorld, :expects 
=> [{:name => :string}], :returns => [:string]
end

这是RoR里面通用的webservice元信息描述。

添加app/controllers/test_controller.rb:

class TestController < ApplicationController
  web_client_api :test, :soap, 
"http://localhost/test/Service.asmx"
                 :namespace 
=> "http://tempuri.org/",
                 :soap_action_base 
=> "http://tempuri.org",
                 :driver_options
=>{:default_encodingstyle => SOAP::EncodingStyle::ASPDotNetHandler::Namespace }

  
def hello
    render_text test.HelloWorld(
"Li Jie")
  end
end

:soap_action_base选项是一个修补,不加这个选项会产生SOAPAction头错误。

运行服务器,在浏览器中访问/test/hello,发现名字为空。经过长时间调试,发现.Net在解析SOAP消息体时,不能处理这种命名空间:

    <n1:HelloWorld xmlns:n1="http://tempuri.org/"
        soap:encodingStyle
="http://schemas.xmlsoap.org/soap/encoding/">
      
<name xsi:type="xsd:string">Li Jie</name>
    
</n1:HelloWorld>

把n1去掉就行了。不过这部分实现在rubylib/soap/rpc/proxy.rb里面,实在不方便修改。为了让这个测试通过,暂时做了点小修改:

  def route(req_header, req_body, reqopt, resopt)
    req_env 
= ::SOAP::SOAPEnvelope.new(req_header, req_body)
    unless reqopt[:envelopenamespace].nil?
      set_envelopenamespace(req_env, reqopt[:envelopenamespace])
    end
    reqopt[:external_content] 
= nil
    conn_data 
= marshal(req_env, reqopt)
    
if ext = reqopt[:external_content]
      mime 
= MIMEMessage.new
      ext.each do 
|k, v|
          mime.add_attachment(v.data)
      end
      mime.add_part(conn_data.send_string 
+ "\r\n")
      mime.close
      conn_data.send_string 
= mime.content_str
      conn_data.send_contenttype 
= mime.headers['content-type'].str
    end

    conn_data.send_string.gsub!(
/:n1/'')
    conn_data.send_string.gsub!(
/n1:/''
)

    conn_data 
= @streamhandler.send(@endpoint_url, conn_data,
      reqopt[:soapaction])
    
if conn_data.receive_string.empty?
      
return nil
    end
    unmarshal(conn_data, resopt)
  end

加粗的2行是我添加的代码,勉强可以让它工作,不过显然不是正确的方法。

不知道是不是.Net库里面的BUG。
posted on 2006-05-14 20:08 qiezi 阅读(454) 评论(0)  编辑 收藏 引用 所属分类: 自家破烂Ruby