【发布时间】:2012-10-12 11:21:07
【问题描述】:
我有一个 VB.NET 2008 程序,它可以访问由 WSDL 定义并使用 SOAP 协议的 Siebel Web 服务。
Siebel Web 服务要求在服务请求中包含一个包含用户名、密码和会话类型的标头,但该标头未在 WSDL 中定义。
因此,当我使用 soapUI 实用程序测试 WSDL 时,WSDL 定义的请求如下所示:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:lov="http://www.siebel.com/xml/LOVService" xmlns:lis="http://www.siebel.com/xml/ListQuery">
<soapenv:Header/>
<soapenv:Body>
<lov:EAILOVGetListOfValues_Input>
<lis:ListsQuery>
<lis:ListQuery>
<lis:Active>Y</lis:Active>
<lis:LanguageCode>ENU</lis:LanguageCode>
<lis:Type>CUT_ACCOUNT_TYPE</lis:Type>
</lis:ListQuery>
</lis:ListsQuery>
</lov:EAILOVGetListOfValues_Input>
</soapenv:Body>
</soapenv:Envelope>
但上述内容不起作用,因为它包含一个缺少用户和会话凭据的空标头。只有当我手动将<soapenv:Header/> 替换为包含用户名、密码和会话类型的标头时,它才有效,如下所示:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:lov="http://www.siebel.com/xml/LOVService" xmlns:lis="http://www.siebel.com/xml/ListQuery">
<soapenv:Header>
<UsernameToken xmlns="http://siebel.com/webservices">TESTUSER</UsernameToken>
<PasswordText xmlns="http://siebel.com/webservices">TESTPASSWORD</PasswordText>
<SessionType xmlns="http://siebel.com/webservices">None</SessionType>
</soapenv:Header>
<soapenv:Body>
<lov:EAILOVGetListOfValues_Input>
<lis:ListsQuery>
<lis:ListQuery>
<lis:Active>Y</lis:Active>
<lis:LanguageCode>ENU</lis:LanguageCode>
<lis:Type>CUT_ACCOUNT_TYPE</lis:Type>
</lis:ListQuery>
</lis:ListsQuery>
</lov:EAILOVGetListOfValues_Input>
</soapenv:Body>
</soapenv:Envelope>
我的问题是我无法弄清楚如何将以上内容翻译成 VB.NET 2008 代码。
将 WSDL 导入 Visual Studio 2008、在 VB 代码中定义服务并引用 Web 服务方法时,我没有问题。但是,我无法理清如何在 VB 中定义 Web 服务,以便更新的标头包含在 Web 服务请求中,而不是空标头。因此,我从 VB 发出的所有服务请求都失败了。
我可以定义一个继承自 SoapHeader 类的类...
Public Class MySoapHeader : Inherits System.Web.Services.Protocols.SoapHeader
Public Username As String
Public Password As String
Public SessionType As String
End Class
...但是如何在 VB 发出的 SOAP 请求中包含此标头?
我用来测试的示例代码是一个带有按钮和列表框的简单表单。
Public Class Form1
Private Sub btnGetLOV_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetLOV.Click
Dim MyService As New wsLOV.EAILOVPortClient
Dim MyInput As New wsLOV.EAILOVGetListOfValues_Input
Dim MyParams(0) As wsLOV.ListQuery
Dim temp As New wsLOV.ListQuery
Dim MyResult As New wsLOV.EAILOVGetListOfValues_Output
temp.Active = "Y"
temp.Type = "CUT_ACCOUNT_TYPE"
temp.LanguageCode = "ENU"
MyParams(0) = temp
MyInput.ListsQuery = MyParams
Dim MyRequest As New wsLOV.EAILOVGetListOfValuesRequest(MyInput)
MyResult = MyService.EAILOVGetListOfValues(MyInput)
End Sub
End Class
代码在子例程的最后一行失败,并显示一条消息,指示请求尚未通过身份验证(错误代码:10944642 错误消息:错误:入站 SOAP 消息 - 会话令牌丢失或无效或已过期),即当我离开包含用户名、密码和会话类型的标头时,我在soapUI 中遇到同样的错误。
我认为我需要将标头添加到端点(每个 http://msdn.microsoft.com/en-us/library/ms731749.aspx 和 http://msdn.microsoft.com/en-us/library/system.servicemodel.configuration.serviceendpointelement.aspx),但我不确定如何在 VB 中执行此操作。
【问题讨论】:
-
服务的 WSDL 损坏,服务提供者需要修复 WSDL。
-
它没有坏。 WSDL 由 Siebel 自动生成。
-
这并不意味着它没有或不能被破坏。
-
关键问题是您的客户端代理是什么,是新服务客户端还是老式网络参考?
-
刚刚编辑了帖子以包含有关我正在使用的测试客户端的其他信息。 wsLOV 名称是由 WSDL 文件定义的服务引用(使用 VS2008 的“添加服务引用”对话框。
标签: vb.net wcf web-services soap siebel