如何向 VB.NET 2008 SOAP 请求添加标头?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13014992/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I add a header to a VB.NET 2008 SOAP request?
提问by robokev
I have a VB.NET 2008 program that accesses a Siebel web service defined by a WSDL and using the SOAP protocol.
我有一个 VB.NET 2008 程序,它访问由 WSDL 定义并使用 SOAP 协议的 Siebel Web 服务。
The Siebel web service requires that a header containing the username, password and session type be included with the service request, but the header is not defined in the WSDL.
Siebel Web 服务要求在服务请求中包含一个包含用户名、密码和会话类型的标头,但该标头未在 WSDL 中定义。
So, when I test the WSDL using the soapUI utility, the request as defined by the WSDL looks like this:
因此,当我使用 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>
But the above does not work because it contains an empty header that is missing user and session credentials. It only works if I manually replace <soapenv:Header/>with a header containing the username, password, and session type as follows:
但上述方法不起作用,因为它包含一个缺少用户和会话凭据的空标头。仅当我手动替换<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>
My problem is that I cannot sort out how to translate the above into VB.NET 2008 code.
我的问题是我无法弄清楚如何将上述内容翻译成 VB.NET 2008 代码。
I have no problem importing the WSDL into Visual Studio 2008, defining the service in VB code and referencing the web service methods. However, I cannot sort out how to define the web service in VB such that the updated header in included in the web service request instead of the empty header. Consequently all my service requests from VB fail.
我将 WSDL 导入 Visual Studio 2008、在 VB 代码中定义服务并引用 Web 服务方法没有问题。但是,我无法弄清楚如何在 VB 中定义 Web 服务,以便在 Web 服务请求中包含更新的标头而不是空标头。因此,我从 VB 发出的所有服务请求都失败了。
I can define a class that inherits from the SoapHeader class...
我可以定义一个继承自 SoapHeader 类的类...
Public Class MySoapHeader : Inherits System.Web.Services.Protocols.SoapHeader
Public Username As String
Public Password As String
Public SessionType As String
End Class
...but how do I include this header in the SOAP request made from VB?
...但是我如何在 VB 发出的 SOAP 请求中包含这个标头?
The sample code I am using to test this is a simple form with a button and a list box.
我用来测试的示例代码是一个带有按钮和列表框的简单表单。
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
The code fails on the last line of the subroutine with a message indicating that the request has not been authenticated (Error Code: 10944642 Error Message: Error: Inbound SOAP Message - Session Token is missing or invalid or has expired) which is the same error I get in soapUI when I leave off the header containing username, password, and session type.
代码在子例程的最后一行失败,并显示一条消息,指示请求尚未通过身份验证(错误代码:10944642 错误消息:错误:入站 SOAP 消息 - 会话令牌丢失或无效或已过期),这是相同的错误当我离开包含用户名、密码和会话类型的标题时,我进入了soapUI。
I believe I need to add the header to the endpoint (per http://msdn.microsoft.com/en-us/library/ms731749.aspxand http://msdn.microsoft.com/en-us/library/system.servicemodel.configuration.serviceendpointelement.aspx) but I am not sure how to do this in VB.
我相信我需要将标头添加到端点(每个http://msdn.microsoft.com/en-us/library/ms731749.aspx和http://msdn.microsoft.com/en-us/library/system .servicemodel.configuration.serviceendpointelement.aspx) 但我不知道如何在 VB 中做到这一点。
回答by robokev
Here is how we resolved this issue. The key seems to be instantiating the endpoint with the additional header, and not trying to add the header after the endpoint is already instantiated.
以下是我们解决此问题的方法。关键似乎是使用附加标头实例化端点,而不是在端点已经实例化后尝试添加标头。
Imports System.ServiceModel.Channels
Imports System.ServiceModel
Public Class Form1
Private Sub btnGetOrg_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetOrgType.Click
' This example code queries the Siebel web service using the SOAP protocol for a list of
' Account (organization) types stored in a List of Values (LOV). The service request
' requires that a SOAP header be added that contains the username, password, and session
' type. We have to add this header because the WSDL file definition generated by Siebel
' does not include the header definition. The WSDL file was added to the VS2008 project as
' a Service Reference named "wsGetLOV"
' Create address headers for special services and add them to an array
Dim addressHeader1 As AddressHeader = AddressHeader.CreateAddressHeader("UsernameToken", "http://siebel.com/webservices", "TESTUSER")
Dim addressHeader2 As AddressHeader = AddressHeader.CreateAddressHeader("PasswordText", "http://siebel.com/webservices", "TESTPASSWORD")
Dim addressHeader3 As AddressHeader = AddressHeader.CreateAddressHeader("SessionType", "http://siebel.com/webservices", "None")
Dim addressHeaders() As AddressHeader = {addressHeader1, addressHeader2, addressHeader3}
' Endpoint address constructor with URI and address headers
' Replace <servername> in the following line with the name of your Siebel server.
' For example: http://actual-server/eai_enu...
Dim endpointAddressWithHeaders As New EndpointAddress(New Uri("http://<servername>/eai_enu/start.swe?SWEExtSource=WebService&SWEExtCmd=Execute&WSSOAP=1"), addressHeaders)
Dim MyService As New wsGetLOV.EAILOVPortClient("EAILOVPort", endpointAddressWithHeaders)
Dim MyInput As New wsGetLOV.EAILOVGetListOfValues_Input
Dim MyOutput As wsGetLOV.EAILOVGetListOfValues_Output
Dim MyList(0) As wsGetLOV.ListQuery
MyList(0) = New wsGetLOV.ListQuery
MyList(0).Active = "Y"
MyList(0).LanguageCode = "ENU"
MyList(0).Type = "CUT_ACCOUNT_TYPE"
MyInput.ListsQuery = MyList
MyOutput = MyService.EAILOVGetListOfValues(MyInput)
Dim myStrings As New List(Of String)
' We use nested loops because the results returned by the service is a list of
' lists though in our case, the result set is a list with a single item (this item
' being a list of multiple items)
For Each myResultList As wsGetLOV.ListResult In MyOutput.ListsResult
For Each myResultValue As wsGetLOV.ListValueResult In myResultList.ListValuesResult
myStrings.Add(myResultValue.Value)
Next
Next
ListBox1.DataSource = myStrings
End Sub
End Class

