Ruby on rails 3 RoR:使用savon(ruby on rails)连接affilinet web服务(登录函数)时出错)->反序列化失败
我尝试通过提供的登录功能登录affilinet web服务。我在Rails3环境3.0.x中工作。我在版本2中使用了RubyonRails gemSavon,它反过来使用soap连接到affilinet。 最新的wsdl可以在这里找到。 我的代码如下所示:Ruby on rails 3 RoR:使用savon(ruby on rails)连接affilinet web服务(登录函数)时出错)->反序列化失败,ruby-on-rails-3,web-services,deserialization,savon,Ruby On Rails 3,Web Services,Deserialization,Savon,我尝试通过提供的登录功能登录affilinet web服务。我在Rails3环境3.0.x中工作。我在版本2中使用了RubyonRails gemSavon,它反过来使用soap连接到affilinet。 最新的wsdl可以在这里找到。 我的代码如下所示: client = Savon.client do wsdl "https://api.affili.net/V2.0/Logon.svc?wsdl" end message = {'Username' => 'username',
client = Savon.client do
wsdl "https://api.affili.net/V2.0/Logon.svc?wsdl"
end
message = {'Username' => 'username', 'Password' => 'password', 'WebServiceType' => 'Publisher'}
response = client.call(:logon, :message => message)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:svc="http://affilinet.framework.webservices/Svc" xmlns:typ="http://affilinet.framework.webservices/types">
<soapenv:Header/>
<soapenv:Body>
<svc:LogonRequestMsg>
<!--Optional:-->
<typ:Username>username</typ:Username>
<!--Optional:-->
<typ:Password>password</typ:Password>
<typ:WebServiceType>Publisher</typ:WebServiceType>
<!--Optional:-->
<typ:DeveloperSettings>
<!--Optional:-->
<typ:SandboxPublisherID>?</typ:SandboxPublisherID>
</typ:DeveloperSettings>
<!--Optional:-->
<typ:ApplicationSettings>
<!--Optional:-->
<typ:ApplicationID>?</typ:ApplicationID>
<!--Optional:-->
<typ:DeveloperID>?</typ:DeveloperID>
</typ:ApplicationSettings>
</svc:LogonRequestMsg>
</soapenv:Body>
</soapenv:Envelope>
由Savon生成的请求:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://affilinet.framework.webservices/Svc" xmlns:ins3="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ins2="http://affilinet.framework.webservices/types" xmlns:ins1="http://schemas.datacontract.org/2004/07/Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF" xmlns:ins0="http://www.microsoft.com/practices/EnterpriseLibrary/2007/01/wcf/validation" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<tns:LogonRequestMsg>
<tns:Password>password</tns:Password>
<tns:WebServiceType>Publisher</tns:WebServiceType>
<tns:Username>username</tns:Username>
</tns:LogonRequestMsg>
</env:Body>
</env:Envelope>
将此请求发送到web服务时,我得到以下错误响应:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:DeserializationFailed</faultcode>
<faultstring xml:lang="en-US">The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://affilinet.framework.webservices/Svc:LogonRequestMsg. The InnerException message was 'Error in line 1 position 775. 'EndElement' 'LogonRequestMsg' from namespace 'http://affilinet.framework.webservices/Svc' is not expected. Expecting element 'Username | Password | WebServiceType'.'. Please see InnerException for more details.</faultstring>
<detail>
<ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<HelpLink i:nil="true"/>
<InnerException>
<HelpLink i:nil="true"/>
<InnerException i:nil="true"/>
<Message>Error in line 1 position 775. 'EndElement' 'LogonRequestMsg' from namespace 'http://affilinet.framework.webservices/Svc' is not expected. Expecting element 'Username | Password | WebServiceType'.</Message>
<StackTrace> at System.Runtime.Serialization.XmlObjectSerializerReadContext.ThrowRequiredMemberMissingException(XmlReaderDelegator xmlReader, Int32 memberIndex, Int32 requiredIndex, XmlDictionaryString[] memberNames)
 ... (loads more) ...
</StackTrace>
<Type>System.ServiceModel.Dispatcher.NetDispatcherFaultException</Type>
</ExceptionDetail>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
你知道怎么了吗
编辑:
soapUI中的请求如下所示:
client = Savon.client do
wsdl "https://api.affili.net/V2.0/Logon.svc?wsdl"
end
message = {'Username' => 'username', 'Password' => 'password', 'WebServiceType' => 'Publisher'}
response = client.call(:logon, :message => message)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:svc="http://affilinet.framework.webservices/Svc" xmlns:typ="http://affilinet.framework.webservices/types">
<soapenv:Header/>
<soapenv:Body>
<svc:LogonRequestMsg>
<!--Optional:-->
<typ:Username>username</typ:Username>
<!--Optional:-->
<typ:Password>password</typ:Password>
<typ:WebServiceType>Publisher</typ:WebServiceType>
<!--Optional:-->
<typ:DeveloperSettings>
<!--Optional:-->
<typ:SandboxPublisherID>?</typ:SandboxPublisherID>
</typ:DeveloperSettings>
<!--Optional:-->
<typ:ApplicationSettings>
<!--Optional:-->
<typ:ApplicationID>?</typ:ApplicationID>
<!--Optional:-->
<typ:DeveloperID>?</typ:DeveloperID>
</typ:ApplicationSettings>
</svc:LogonRequestMsg>
</soapenv:Body>
</soapenv:Envelope>
也许Savon和soapUI生成的请求之间的差异是关键!?特别是不同的名称空间:svc/typ与env/tns。有什么想法吗?如何告诉Savon将svc命名空间用于LogonRequestsMsg?查看Affili.net的WSDL,发现用户名、密码、WebserviceType等的命名空间错误 在再次查看示例后,为名称空间编辑。用户名、密码和WebServiceType在命名空间ins2中定义=http://affilinet.framework.webservices/types 在你的案例中,ins2标记了它 快速而肮脏的克服方法是
client = Savon.client do
wsdl "https://api.affili.net/V2.0/Logon.svc?wsdl"
end
message = {'ins2:Username' => 'username',
'ins2:Password' => 'password',
'ins2:WebServiceType' => 'Publisher'}
response = client.call(:logon, :message => message)
查看Affili.net的WSDL,它显示用户名、密码、WebserviceType等具有错误的命名空间 在再次查看示例后,为名称空间编辑。用户名、密码和WebServiceType在命名空间ins2中定义=http://affilinet.framework.webservices/types 在你的案例中,ins2标记了它 快速而肮脏的克服方法是
client = Savon.client do
wsdl "https://api.affili.net/V2.0/Logon.svc?wsdl"
end
message = {'ins2:Username' => 'username',
'ins2:Password' => 'password',
'ins2:WebServiceType' => 'Publisher'}
response = client.call(:logon, :message => message)
我认为问题在于名称空间顺序,在几个请求看到名称空间中的不同顺序之后 此代码适用于我savod版本1,覆盖名称空间:
message = {
'ins0:Username' => 'XXXXXXX',
'ins0:Password' => 'XXXXXXX',
'ins0:WebServiceType' => 'XXXXXX',
:order! => ['ins0:Username', 'ins0:Password', 'ins0:WebServiceType']
}
@client.wsdl.document = 'https://api.affili.net/V2.0/Logon.svc?wsdl'
response = @client.request :logon do
soap.body = message
soap.namespaces["xmlns:ins0"] = "http://affilinet.framework.webservices/types"
soap.namespaces["xmlns:ins1"] = "http://schemas.microsoft.com/2003/10/Serialization/Arrays"
soap.namespaces["xmlns:ins2"] = "http://www.microsoft.com/practices/EnterpriseLibrary/2007/01/wcf/validation"
soap.namespaces["xmlns:ins3"] = "http://schemas.datacontract.org/2004/07/Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF"
end
我认为问题在于名称空间顺序,在几个请求看到名称空间中的不同顺序之后 此代码适用于我savod版本1,覆盖名称空间:
message = {
'ins0:Username' => 'XXXXXXX',
'ins0:Password' => 'XXXXXXX',
'ins0:WebServiceType' => 'XXXXXX',
:order! => ['ins0:Username', 'ins0:Password', 'ins0:WebServiceType']
}
@client.wsdl.document = 'https://api.affili.net/V2.0/Logon.svc?wsdl'
response = @client.request :logon do
soap.body = message
soap.namespaces["xmlns:ins0"] = "http://affilinet.framework.webservices/types"
soap.namespaces["xmlns:ins1"] = "http://schemas.microsoft.com/2003/10/Serialization/Arrays"
soap.namespaces["xmlns:ins2"] = "http://www.microsoft.com/practices/EnterpriseLibrary/2007/01/wcf/validation"
soap.namespaces["xmlns:ins3"] = "http://schemas.datacontract.org/2004/07/Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF"
end
为了调试SOAP层,我强烈建议安装SsoapUI。然后,您可以测试SOAP消息以确保该层正常工作。如果还需要的话,你可以和萨冯打交道。您描述的问题与Savon无关。要调试SOAP层,我强烈建议安装SsoapUI。然后,您可以测试SOAP消息以确保该层正常工作。如果还需要的话,你可以和萨冯打交道。您描述的问题与Savon无关。更改名称空间没有帮助。soapUI表示用户名、密码和WebServiceType的命名空间为“typ”:。。。用户名密码发布者。。。但是把它改成“典型”也没用?!Savon真的在处理WSDL错误吗?不管出于什么原因,Savon给名称空间起了一个不同于soapUI的名称。如果查看原始wsdl文档,则会发现tns:LogonRequest为消息类型。我不是解释WSDLs的专家。我采取务实的方法,在发送请求时调试来自服务器的内容。Savon为您提供了很好的日志记录来查找它。您是否尝试过在您的环境中使用完全相同的名称空间前缀来使用我的示例?我完全按照您的建议进行了尝试,但得到了相同的错误消息,即上面第一篇文章中的错误消息。不知道命名空间中的“EndElement”“LogonRequestMsg”是什么意思,这是不需要的。错误消息中应包含元素“Username | Password | WebServiceType”。这些数据由Savon根据给定的WSDL提供,其余的请求由Savon构建。显然,Savon正在生成一个不符合要求的请求,但是。发现在我的计算机和你的计算机上创建消息的方式不同。我编辑了答案,请重试。我发现我必须使用ins0作为前缀,并且必须在用户名、密码和WebServiceType上使用它。但这确实解决了我的问题。更改名称空间没有帮助。soapUI表示用户名、密码和WebServiceType的命名空间为“typ”:。。。用户名密码发布者。。。但是把它改成“典型”也没用?!Savon真的在处理WSDL错误吗?不管出于什么原因,Savon给名称空间起了一个不同于soapUI的名称。如果查看原始wsdl文档,则会发现tns:LogonRequest为消息类型。我不是解释WSDLs的专家。我采取务实的方法,在发送请求时调试来自服务器的内容。Savon为您提供了很好的日志记录来查找它。您是否尝试过在您的环境中使用完全相同的名称空间前缀来使用我的示例?我完全按照您的建议进行了尝试,但得到了相同的错误消息,即上面第一篇文章中的错误消息。不知道命名空间中的“EndElement”“LogonRequestMsg”是什么意思,这是不需要的。错误消息中应包含元素“Username | Password | WebServiceType”。这些数据由Savon根据给定的WSDL提供,其余的请求由Savon构建。显然Savon正在构建一个不符合要求的请求,thoug
h、 发现在我的机器和你的机器上创建邮件的方式不同。我编辑了答案,请重试。我发现我必须使用ins0作为前缀,并且必须在用户名、密码和WebServiceType上使用它。但这确实为我解决了问题。