助けて下さい! ASMX Web サービスに接続するにはどうしたらいいのですか?


引き続き、米国のサポートチームで公開している Blog の翻訳を紹介させてください。
もちろん、Windows ストア アプリからも  ASP.NET Web サービス (ASMX サービス) を使うことができます。今回は Windows ストア アプリで ASMX Web サービスを使うための初歩についてまとめた記事を翻訳してみたいと思います。

Help me! How do I connect to an ASMX web service?

MSDN フォーラムのモデレータとして、Windows ストア アプリからの、さらには最近の Windows Phone 開発の Windows ストア ソリューション チームへの統合に伴い、Windows Phone 8アプリからの、Web サービスのメソッドを初期化し、呼び出し、認証する方法についての問い合わせを、私は多数受け付けました。このブログではASMX Web サービスをモバイル アプリから使用する方法について説明します。

 

ASMX Web サービス

ASMX Web サービスが現れてから久しく今では広く使われています。このサービスでは SOAP 構造 (XML 形式のメッセージの連なり) によって、HTTP 上でクライアントとサーバーの間でデータのやり取りを行います。 この SOAP 構造の作成とそのためのメソッド呼び出しは手書きするには複雑かもしれませんが、幸いなことに、.NET 以降の Visual Studio はどれもクラス プロキシの自動生成をサポートしていて、 Web サービス内のメソッドを呼び出すことは自分のプロジェクト内のメソッドを呼ぶのと同じくらい簡単です。ASMX Web サービスへの参照の作成はたった数ステップで行えます。この手順はストアのプロジェクトでも Phone のプロジェクトでも同じです。

 

1) プロジェクトのソリューション エクスプローラーで、参照設定を右クリックし、参照の追加を選択します

 

 

2) ダイアログボックスが現れるので、 Web サービスの URL を入力し移動ボタンを押します。

 

 

3) サービス枠に Web サービス名が現れます。 Web サービスにプロジェクト内から参照するための名前空間 (お好きな名前) をつけてください。OKボタンを押します。 この名前は Service References に現れます。下の一覧にあるように、私のプロジェクトには 2 つの名前空間があり、これからお見せする 2 つの別の ASMX Web サービスに対応しています。

 

 

Windows ストア アプリから匿名認証により ASMX Web サービスを利用する

Web サービスはアクセス許可が必要でない場合は匿名認証されているとみなされます。サーバーはだれが情報をリクエストしてきたかに関係なくすべてのリクエストを処理していいことになっています。これがインターネット上における多くの Web サービスの現状です。

ご参考までに、私がストア アプリケーションから呼び出すメソッドのソース コードは以下のようになります。

 1: [WebMethod]
 2: public List<string> GetStrings(int StartNumber, int EndNumber)
 3: {
 4:      List<string> MyList = new List<string>();
 5:      for (int i = StartNumber; i <= EndNumber; i++)
 6:      {
 7:           MyList.Add("AuthASMXService String #" + i.ToString());
 8:      }
 9:      return MyList;
 10: }

… そして、これが上記により初期化されたウェブ サービスを呼ぶコードです。

 1: private async void ASMXWebServiceInvoke_Click_1(object sender, RoutedEventArgs e)
 2: {
 3:     ASMXWebServiceReference.WebService1SoapClient MyASMXWebServiceClient 
          = new ASMXWebServiceReference.WebService1SoapClient();
 4:     ASMXWebServiceReference.GetStringsResponse MyStringsResponse = await 
          MyASMXWebServiceClient.GetStringsAsync(10, 20);
 5:     ASMXWebServiceReference.ArrayOfString MyStrings = 
          MyStringsResponse.Body.GetStringsResult;
 6:     ASMXGridView.ItemsSource = MyStrings;
 7: }

  

それでは各行ごとに見ていきましょう。 (3 ~ 6行目)

  • まず、 Web サービスの名前空間でオブジェクトを初期化しなくてはなりません。
  • 初期化した Web サービスから、GetStrings メソッドを非同期に呼び出し、必要な引数を渡します。 応答がありますが、 Web サービスの返値のデータ型ではありません。ネットワークの呼び出しにかかわるすべての情報と、 Web サービスそのものの応答が含まれています。
  • 応答を格納するオブジェクト (MyStrings) を初期化し、実際に応答を格納します。
  • これで応答をグリッドビューで使うことができます。データが埋まったグリッドビューはこのようになります。

 

 

Windows ストア アプリケーションから Windows 認証を用いて ASMX Web Service を取り込む

多くの Web サービス、特に企業内の業務アプリケーションにはセキュリティが求められます。これらの Web サービスにアクセスするには、認証情報を渡すことが必要です。以下にそのための処理を行うコードを記述します。

 1:  private async void AuthASMXWebServiceInvoke_Click_1(object sender, RoutedEventArgs e)
 2:         {
 3:             bool ShowError = false;
 4:             System.Exception MyException = new Exception();
 5:             try
 6:             {
 7:  
 8:                 System.ServiceModel.BasicHttpBinding MyHttpBinding = 
                      new System.ServiceModel.BasicHttpBinding(
                      System.ServiceModel.BasicHttpSecurityMode.TransportCredentialOnly);
 9:                 MyHttpBinding.Security.Transport.ClientCredentialType = 
                      System.ServiceModel.HttpClientCredentialType.Windows;
 10:  
 11:                 System.ServiceModel.EndpointAddress MyAuthASMXWebServiceAddress = 
                       new System.ServiceModel.EndpointAddress(new Uri("http://localhost/AuthWebService2.asmx"));
 12:                 AuthASMXWebServiceReference2.AuthWebService2SoapClient 
                       MyAuthWebServiceClient = new AuthASMXWebServiceReference2.
                       AuthWebService2SoapClient(MyHttpBinding, MyAuthASMXWebServiceAddress);
 13:                 MyAuthWebServiceClient.ClientCredentials.Windows.ClientCredential.Domain 
                       = "localhost";
 14:                 MyAuthWebServiceClient.ClientCredentials.Windows.ClientCredential.UserName
                       = "SpecialUser";
 15:                 MyAuthWebServiceClient.ClientCredentials.Windows.ClientCredential.Password
                       = "Password123";
 16:  
 17:                 AuthASMXWebServiceReference2.GetStringsResponse MyStringsResponse = 
                       await MyAuthWebServiceClient.GetStringsAsync(20, 30);
 18:                 AuthASMXWebServiceReference2.ArrayOfString MyStrings = 
                       MyStringsResponse.Body.GetStringsResult;
 19:                 AuthASMXGridView.ItemsSource = MyStrings;
 20:  
 21:             }
 22:             catch (Exception ex)
 23:             {
 24:                 ShowError = true;
 25:                 MyException = ex;
 26:             }
 27:             if (ShowError)
 28:             {
 29:                 var MyMessageBox = new Windows.UI.Popups.MessageDialog(MyException.Message);
 30:                 await MyMessageBox.ShowAsync();
 31:             }
 32:         }

 

 1:  private async void AuthASMXWebServiceInvoke_Click_1(object sender, RoutedEventArgs e)
 2:         {
 3:             bool ShowError = false;
 4:             System.Exception MyException = new Exception();
 5:             try
 6:             {
 7:  
 8:                 System.ServiceModel.BasicHttpBinding MyHttpBinding = new 
                      System.ServiceModel.BasicHttpBinding
                      (System.ServiceModel.BasicHttpSecurityMode.TransportCredentialOnly);
 9:                 MyHttpBinding.Security.Transport.ClientCredentialType = 
                      System.ServiceModel.HttpClientCredentialType.Windows;
 10:  
 11:                 System.ServiceModel.EndpointAddress MyAuthASMXWebServiceAddress = new 
                       System.ServiceModel.EndpointAddress(new Uri(
                       "http://localhost/AuthWebService2.asmx"));
 12:                 AuthASMXWebServiceReference2.AuthWebService2SoapClient
                       MyAuthWebServiceClient = new AuthASMXWebServiceReference2.
                       AuthWebService2SoapClient(MyHttpBinding, MyAuthASMXWebServiceAddress);
 13:                 MyAuthWebServiceClient.ClientCredentials.Windows.ClientCredential.Domain 
                       = "localhost";
 14:                 MyAuthWebServiceClient.ClientCredentials.Windows.ClientCredential.UserName 
                       = "SpecialUser";
 15:                 MyAuthWebServiceClient.ClientCredentials.Windows.ClientCredential.Password 
                       = "Password123";
 16:  
 17:                 AuthASMXWebServiceReference2.GetStringsResponse MyStringsResponse 
                       = await MyAuthWebServiceClient.GetStringsAsync(20, 30);
 18:                 AuthASMXWebServiceReference2.ArrayOfString MyStrings
                       = MyStringsResponse.Body.GetStringsResult;
 19:                 AuthASMXGridView.ItemsSource = MyStrings;
 20:  
 21:             }
 22:             catch (Exception ex)
 23:             {
 24:                 ShowError = true;
 25:                 MyException = ex;
 26:             }
 27:             if (ShowError)
 28:             {
 29:                 var MyMessageBox = new Windows.UI.Popups.MessageDialog(MyException.Message);
 30:                 await MyMessageBox.ShowAsync();
 31:             }
 32:         }

 

このメソッドには例外処理のルーチンが含まれていて、 Web サービスと通信時に発生したエラーを取ることができます。たとえば、パスワードを間違った値に変更して認証しようとすると、次のような画面表示になります。

 

 このコードが匿名のコードと違う主な点は、呼び出し元のコードに認証情報を渡すことです。

  • 8 行目では HTTP バインディング オブジェクトを初期化し、これにより使用する認証方法を指定することができます。また、コンストラクタに渡す引数で、このバインディングで SSL を使用せずセキュアではない方法で認証情報をおくることを許可しています。これを変更して認証情報を渡すのに SSL を必須とすることも可能です。
  • 9 行目では認証方法を Windows 認証、ネゴシエートとも呼ばれますが、に設定しています。このほかには、基本認証、NTLM、クライアント証明書、および、ダイジェストの認証方法があります。
  • 認証情報を渡すときには、それがどこに行くかを知っておくことが重要です - つまるところ、これは保護された情報にアクセスするためのリソースです。11 行目で最終目的地をこの Web サービスの URL に設定します。
  • Web サービス オブジェクトを初期化するにあたり、HTTP バインディング オブジェクトとエンドポイントを渡します。これによりオブジェクトが変更され、Web サービスと通信するときに Windows 認証をすることが指定されます。
  • 最後に 13, 14 および、15 行目で Web サービスにアクセスするためのドメイン、ユーザー名、そしてパスワードを設定します。

残りのウェブサービス呼び出しは匿名呼び出しのときと同じです。以下が完成したウェブサービス呼び出しです。

 

 

結論

Web サービスへアクセスすることはモバイル サービスをプログラムするうえで驚くほど重要な部分です。ここに提示したコードがあなたのお役に立ち、アプリケーションを設計するうえでの一助となることを願っています。以下にどうぞお気軽にコメントをお寄せください。

それから、ツイッターで @WSDevSol をフォローしてください!