首先寫一個(gè)簡(jiǎn)單的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項(xiàng)目里,添加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選項(xiàng)是一個(gè)修補(bǔ),不加這個(gè)選項(xiàng)會(huì)產(chǎn)生SOAPAction頭錯(cuò)誤。
運(yùn)行服務(wù)器,在瀏覽器中訪問/test/hello,發(fā)現(xiàn)名字為空。經(jīng)過長(zhǎng)時(shí)間調(diào)試,發(fā)現(xiàn).Net在解析SOAP消息體時(shí),不能處理這種命名空間:
????<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去掉就行了。不過這部分實(shí)現(xiàn)在rubylib/soap/rpc/proxy.rb里面,實(shí)在不方便修改。為了讓這個(gè)測(cè)試通過,暫時(shí)做了點(diǎn)小修改:
??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行是我添加的代碼,勉強(qiáng)可以讓它工作,不過顯然不是正確的方法。
不知道是不是.Net庫(kù)里面的BUG。