首先写一个简单的webservice:
在RoR项目里,添加app/apis/test_api.rb:
这是RoR里面通用的webservice元信息描述。
添加app/controllers/test_controller.rb:
:soap_action_base选项是一个修补,不加这个选项会产生SOAPAction头错误。
运行服务器,在浏览器中访问/test/hello,发现名字为空。经过长时间调试,发现.Net在解析SOAP消息体时,不能处理这种命名空间:
把n1去掉就行了。不过这部分实现在rubylib/soap/rpc/proxy.rb里面,实在不方便修改。为了让这个测试通过,暂时做了点小修改:
加粗的2行是我添加的代码,勉强可以让它工作,不过显然不是正确的方法。
不知道是不是.Net库里面的BUG。
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;
}
}
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
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
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 >
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
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。