locked
Webサービス呼び出し時 RRS feed

  • 質問

  • Silverlight、VBで開発を行っております。

    Silverlight4からWebサービスを呼び出すときに、EventHandlerをXXXCompletedに追加するコードが

    あるのですが、参考にしているHPにも、

    proxy.CountUsersCompleted += New _
                    EventHandler(Of CountUsersCompletedEventArgs)(proxy_CountUsersCompleted) proxy.CountUsersAsync()

    のように書いてあるので同様に処理を入れたのですが、

    エラー 1 'Public Event CountUsersCompleted(sender As Object, e As ServiceReference1.CountUsersCompletedEventArgs)' はイベントであるため、直接呼び出すことはできません。イベントを発生させるには 'RaiseEvent' ステートメントを使用してください。 

    というエラーがでてしまうのですが。何がいけないのでしょうか?

     

    お手数ではございますがどなたかご教授願います。

    2011年2月8日 11:58

回答

  • 誤りコード
    ' クライアントサービス終了時のイベントハンドラの登録
    AddHandler proxy.CloseCompleted, AddressOf proxy_CountUsersCompleted
    
    正しいコード
    ' クライアントサービス終了時のイベントハンドラの登録
    AddHandler proxy.CountUsersCompleted, AddressOf proxy_CountUsersCompleted
    
    サービス参照で自動生成されるサービスクライアントクラスには、○○Asyncメソッドと○○Completedイベントがセットで定義されます。よって、CountUsersAsyncメソッドが終了したときに発行されるイベントは、CountUsersCompletedイベントになります。
    • 回答としてマーク ohzeki 2011年2月10日 6:16
    2011年2月10日 2:11

すべての返信

  • Silverlightのサービスコールは、非同期になります。よって、

    1.サービスをコールする。このとき、サービスコールメソッド(下の例ですとDoWorkAsyncメソッド)は、サービスから戻り値が帰ってくるのを待たずに終了する。

    2.サービスからの戻り値が返ってきたとき、Service1Clientは、DoWorkCompletedを呼び出す。

    3.DoWorkCompletedに登録したClient_DoWorkCompletedEventArgsが呼ばれるので、このメソッド内でサービスからの戻り値を処理する。

    という、流れになります。

      Public Sub New()
        InitializeComponent()
    
        'サービスクライアントを生成
        Dim client As New Service1Client()
    
        'クライアントにサービス終了時のイベントハンドラを登録
        AddHandler client.DoWorkCompleted, AddressOf Client_DoWorkCompletedEventArgs
    
        'サービスコール開始
        client.DoWorkAsync()
      End Sub
    
      Private Sub Client_DoWorkCompletedEventArgs(ByVal sender As Object, ByVal e As DoWorkCompletedEventArgs)
        'サービスからの戻り値を取得。
        Dim result As IEnumerable(Of String) = e.Result
      End Sub
    

    ちなみに、コンパイルエラー

    >エラー 1 'Public Event CountUsersCompleted(sender As Object,~

    は、単純にVB.Netの構文が間違っているために起きています。C#とは異なりイベントハンドラの登録はAddHandlerを使えばOKです。

    2011年2月8日 14:48
  • 上記のやり方で解決できました。ありがとうございました。

    さらになのですが、

    このまま実行すると、別問題だと思うのですが、

    ---への要求試行時にエラーが発生しました。これは、正しいクロスドメイン ポリシーを適用せずにクロスドメインでサービスにアクセスしようとしたことか、SOAP サービスには適していないポリシーが原因で発生した可能性があります。サービスの所有者に問い合わせて、クロスドメイン ポリシー ファイルを公開し、SOAP 関連の HTTP ヘッダーが送信されるようにしてもらう必要がある可能性もあります。このエラーは、Web サービス プロキシで InternalsVisibleToAttribute 属性を使わずに内部型を使用した場合にも発生することがあります。詳細については、内部例外を参照してください。

    というエラーが出てしまいます。

    別のトピックで同様のエラーについて書かれていたのですがどうも自分の知識不足で

    理解できないのですが、ご存知でしたら教えていただけませんか?

    そのトッピックスには、

    Visual Studio 2008からSilverlightプロジェクトを作り、同時にホスト用のWebプロジェクトも作ると問題は簡単になると思います。
    Webプロジェクトを右クリックして[追加]-[新しい項目の追加]で、[Silverlight対応のWCFサービス]を選択して、サービスを作成します。

    今回私はサービスをクライアントサービスを構築する上で上記手順で作成したのですが、何がいけなかったのでしょうか?

    大変お手数ではございますがご教授お願い致します。

     

    2011年2月9日 2:12
  • WCFCallTestソリューション
    |-WCFCallTest … Silverlightプロジェクト
    |-WCFCallTest.Web … WCFCallTestTestPage.htmlとか置いてあるプロジェクト
    というソリューション構成とします。このとき、WCFCallTest.WebプロジェクトにWCFサービスクラスを追加したならば、クロスドメインポリシー違反にはなりません。なぜならば、SilverlightをホストしているサーバとWCFサービスを公開しているサーバが同一ドメインになるからです。
    一方、WCFサービス用のプロジェクトを新しく作った場合は話しが異なってきます。
    WCFCallTestソリューション
    |-WCFCallTest … Silverlightプロジェクト
    |-WCFCallTest.Web … WCFCallTestTestPage.htmlとか置いてあるプロジェクト
    |-WCFPublice … WCFサービスクラスを配置するプロジェクト。Silverlightアプリは、このサーバプロジェクトのWCFサービスにアクセスしたいと想定。
    このソリューション構成の場合は、クロスドメイン設定が必要になります。下記のページなどを参考に設定を行ってください。

    Silverlightとサーバーサービスの連携
    http://codezine.jp/article/detail/3596?p=3

    ドメインの境界を越えてサービスを利用できるようにする
    http://msdn.microsoft.com/ja-jp/library/cc197955(VS.95).aspx
    2011年2月9日 3:54
  • ご回答ありがとうございます。

    確認しましたところ、ご回答いただきました前者のように作成しております。

    WCFCallTestソリューション
    |-WCFCallTest … Silverlightプロジェクト
    |-WCFCallTest.Web … WCFCallTestTestPage.htmlとか置いてあるプロジェクト
                   … WFCService1.svcを作成
    上記の通り、

    WCFCallTest.WebにWFCService1.svcを作成し、WCFCallTestでWFCService1.svcを

    サービス参照の追加で参照しております。

    ということは、

    ”正しいクロスドメイン ポリシーを適用せずにクロスドメインでサービスにアクセスしようとした”

    というエラーにはならないんですよね。他に何がいけないのでしょうか?

    度重なる質問で申し訳ありませんがよろしくお願いいたします。

    2011年2月9日 4:46
  • Silverlihgtを実行したとき、ブラウザのURLが
    D:\Temp\WCFCallTest\WCFCallTest\Bin\Debug\WCFCallTestTestPage.html
    のようになっていないでしょうか?
    この場合、スタートアッププロジェクトがWebサービスプロジェクトにすれば問題は解決すると思います。
    VisualStudioのソリューションエクスプローラでWCFCallTest.Webを右クリックし、「スタートアッププロジェクトに設定」を選択してください。ソリューションエクスプローラで、WCFCallTest.Webプロジェクトが太字になっていれば設定成功です。VisualStudioで実行するとブラウザのアドレスが「http://localhost:51604/WCFCallTestTestPage.aspx」などとなっているはずです。
    ちなみに、
    http://localhost:51604/WCFCallTestTestPage.aspx
    D:\Temp\WCFCallTest\WCFCallTest\Bin\Debug\WCFCallTestTestPage.html
    の挙動の違いを理解することは重要となります。ぜひ調べてみてください。
    2011年2月9日 5:45
  • 無事解決できました。ありがとうございました。

    この問題で無事にサービス側で作成したデータを取得できるかと思っていたのですが、

     Public Sub New()
            InitializeComponent()

            ' サービスクライアントの生成
            Dim proxy As New CustomerServiceClient()
            ' クライアントサービス終了時のイベントハンドラの登録
            AddHandler proxy.CloseCompleted, AddressOf proxy_CountUsersCompleted
            ' サービスコール開始
            proxy.CountUsersAsync()

        End Sub

        Private Sub proxy_CountUsersCompleted(ByVal sender As Object, _
           ByVal e As CountUsersCompletedEventArgs)

            If Not (e.Error Is Nothing) Then
                userCountResult.Text = "Error getting the number of users"
            Else
                userCountResult.Text = "The number of users: " + e.Result
            End If

        End Sub

    End Class

    ”' クライアントサービス終了時のイベントハンドラの登録”で登録したメソッドが実行されないのですが、

    サービスコール終了メソッドを呼んでみたりしたのですがだめでした。どのようにしたらproxy_CountUsersCompleted

    メソッドが実行されるのでしょうか?

    再度ご教授いただけると幸いです。よろしくお願いいたします。

     

    2011年2月9日 7:04
  • 誤りコード
    ' クライアントサービス終了時のイベントハンドラの登録
    AddHandler proxy.CloseCompleted, AddressOf proxy_CountUsersCompleted
    
    正しいコード
    ' クライアントサービス終了時のイベントハンドラの登録
    AddHandler proxy.CountUsersCompleted, AddressOf proxy_CountUsersCompleted
    
    サービス参照で自動生成されるサービスクライアントクラスには、○○Asyncメソッドと○○Completedイベントがセットで定義されます。よって、CountUsersAsyncメソッドが終了したときに発行されるイベントは、CountUsersCompletedイベントになります。
    • 回答としてマーク ohzeki 2011年2月10日 6:16
    2011年2月10日 2:11
  • 無事解決できました。

    色々ご丁寧に教えていただき本当にありがとうございました。

    2011年2月10日 6:16