3

WSDL で定義され、SOAP プロトコルを使用して Siebel Web サービスにアクセスする VB.NET 2008 プログラムがあります。

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 サービス メソッドを参照することに問題はありません。ただし、空のヘッダーの代わりに更新されたヘッダーが Web サービス要求に含まれるように、VB で 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 でこれを行う方法がわかりません。

4

1 に答える 1

3

この問題を解決した方法は次のとおりです。キーは追加のヘッダーを使用してエンドポイントをインスタンス化しているようで、エンドポイントが既にインスタンス化された後にヘッダーを追加しようとしていません。

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
于 2012-10-29T15:36:54.587 に答える