vb.net - 如何向 VB.NET 2008 SOAP 请求添加 header ?

标签 vb.net wcf web-services soap siebel

我有一个 VB.NET 2008 程序,它访问由 WSDL 定义并使用 SOAP 协议(protocol)的 Siebel Web 服务。

Siebel Web 服务要求包含用户名、密码和 session 类型的 header 包含在服务请求中,但该 header 未在 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>

但上面的内容不起作用,因为它包含一个缺少用户和 session 凭据的空 header 。它只有在我手动替换 <soapenv:Header/> 时才有效带有包含用户名、密码和 session 类型的 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 服务请求中包含更新的 header 而不是空 header 。因此,我所有来自 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 请求中包含此 header ?

我用来测试它的示例代码是一个带有按钮和列表框的简单表单。

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 消息 - session token 丢失或无效或已过期)这是当我离开包含用户名、密码和 session 类型的 header 时,我在 soapUI 中遇到了同样的错误。

我认为我需要将 header 添加到端点(根据 http://msdn.microsoft.com/en-us/library/ms731749.aspxhttp://msdn.microsoft.com/en-us/library/system.servicemodel.configuration.serviceendpointelement.aspx ),但我不确定如何在 VB 中执行此操作。

最佳答案

以下是我们解决此问题的方法。关键似乎是用附加 header 实例化端点,而不是在端点已经实例化后尝试添加 header 。

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

关于vb.net - 如何向 VB.NET 2008 SOAP 请求添加 header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13014992/

相关文章:

VB.NET 以最少的步骤自定义复杂排序

java - 在vb.net中使用IComparable来比较石头剪刀布游戏中的武器(与JAVA中的Comparable相同)

.net - 对象不为空的排序列表

wpf - 在 MVVM 中调用 WCF 服务?

web-services - 响应式网站 CSS 未通过梭子鱼 SSL VPN 加载

使用 Spring 3.0 Rest Webservice 的 Jquery ajax 跨域策略问题

sql-server - 新 SQL Server 连接的方法/属性错误

.net - 如何使用 WCF 跟踪查看器查看在线发送的原始 SOAP 信息?

c# - 将关系数据库存储为 XML

java - 使用 Jersey 为 REST Web 服务发送 HashMap