C# と WSDL のプロキシ コードで SOAP サービスを利用する

> [!NOTE]
> この記事では [.NET WCF クライアントライブラリ][04] について記述しています。Microsoft Docs によると、サーバーサイドの [WCF サービスの実装は .NET 5 に含まれなくなる][05] とのことです

　SOAP サービスを C# の コンソールアプリケーション で利用する手順です。OS は Windows，フレームワークは .NET Framework 4.8，IDE は Visual Studio 2019 を使用します。

　タイトルのとおり、サービス エンドポイント側の構築ではなく、クライアント側からサービスを利用することに視点を置いています。また、ゼロからコードを組み込むわけではなく、WCF Web Service Reference ツールを利用して「WCF クライアント プロキシ コード」と呼ばれるクラス ファイルをつくって、Web サービスのアクセスに利用します

1. [Postman で Web サービスを確認する][1]
2. [WCF クライアント プロキシ コードを作成する][2]

## 1. Postman で Web サービスを確認する

　サービスプロキシの生成に必要になる URL とメタデータを Postman で確認しておきます。URL とメタデータはプロキシ コードを生成する場面で必要になります。[WSDL 1.1][11] に準拠してサービスが記述されている場合、その内容から Web サービスで扱える操作とデータを窺うことができます

| WSDL の要素 | 内容 |
|:--|:--|
| **Types** | Web サービスで使えるデータ型 |
| **Message** | 各操作（オペレーション）で通信できるデータ |
| **Port Type/Operation** | エンドポイントがサポートする操作（オペレーション） |
| **Binding** | Port Type ごとのプロトコルとデータ形式 |

　DISCO に対応しているシステムの場合、Web サービスのエンド ポイントを一覧で調べる機能を備えていることがあります。 Dynamics NAV の場合は `https://{HOSTNAME}:7047/{INSTANCE_NAME}/WS/services` という URL から使用可能な Web サービスを探索できます（詳しいことは不明ですが [DISCO][12] 自体はかなり古そうな仕様です・・）

```xml:/WS/services
<discovery xmlns="http://schemas.xmlsoap.org/disco/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <contractRef ref="https://localhost:7047/DynamicsNAV100/WS/SystemService" xmlns="http://schemas.xmlsoap.org/disco/scl/"/>
    <contractRef ref="https://localhost:7047/DynamicsNAV100/WS/Page/ItemList" xmlns="http://schemas.xmlsoap.org/disco/scl/"/>
    <contractRef ref="https://localhost:7047/DynamicsNAV100/WS/Page/powerbifinance" xmlns="http://schemas.xmlsoap.org/disco/scl/"/>
    <contractRef ref="https://localhost:7047/DynamicsNAV100/WS/Page/SalesOrder" xmlns="http://schemas.xmlsoap.org/disco/scl/"/>
</discovery>
```

[11]: https://www.w3.org/TR/wsdl.html
[12]: https://docs.microsoft.com/ja-jp/previous-versions/msdn/architecture-center/cc440101(v=vs.71)

## 2. WCF クライアント プロキシ コードを作成する

　.NET Framework に含まれる機能を利用して **WCF クライアント プロキシ コード** （以下、プロキシ コード）を生成します。これは SOAP で使用されるメッセージのデータ型が定義された C# 等のクラス ファイルであり、このプロキシ コードを利用することで Web サービスを呼び出すためのコーディングの手間を大幅に省略することができます。

　プロキシ コードを生成する方法はいくつかあり、Visual Studio や WSDL.exe を使う方法があります。Microsoft Docs では Visual Studio の説明の方が新しいようなので、理由がなければ Visual Studio を使う方が良いようです。

1. Visual Studio WCF (Windows Communication Foundation) Web Service Reference Provider
2. WSDL.exe (Web Services Description Language Utility)

<!-- NOTE: SvcUtil.exe というのもある・・・ -->

### Visual Studio WCF Web Service Reference を使用する方法

　Visual Studio を使用する方法は Microsoft Docs に詳しい説明が既にあります。Visual Studio の GUI に URL または WSDL ファイルのパスを入力するだけで Reference.cs という名前のプロキシ コードが生成されます。メイン ルーチン中にある処理等から生成されたプロキシ コードを参照して使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58/ea052c87-f890-1522-12f9-b7937e908876.png)

**参考リンク**

- [Microsoft Docs - Use the WCF Web Service Reference Provider Tool][21]
- [Microsoft Docs - How to: Add, update, or remove a WCF data service reference][22]

### WSDL.exe を使用する方法

　.NET Framework SDK に含まれる WSDL.exe を使用します。WSDL.exe がある場所は、SDK のバージョンによって異なりますが、Windows 10，.NET Framework 4.8 であれば %PROGRAMFILES(X86)%\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools にあります。オプションの `/language` で CS，VB 等を指定することができます。

| オプション | 説明 |
|:--|:--|
| /language:<言語> | 生成されるプロキシ クラスに使用する言語です。CS，VB，JS，VJS，CPP から選択できます。既定は CS (CSharp) です。 短い形式は `/l:` です。 |
| /out:<ファイル名またはディレクトリ パス> | 生成されたプロキシ コードのファイル名またはディレクトリ パスです。既定のファイル名は サービス名から派生しています。短い形式は `/o:` です。 |

　例えば ItemCard.wsdl から ItemCard_Service.cs を生成する場合は次のように WSDL.exe を実行します。

```shell-session:wsdl.exe
>"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\wsdl.exe" ^
More? .\ItemCard.wsdl
Microsoft(R) Web Services Description Language Utility
[Microsoft (R) .NET Framework, Version 4.8.3928.0]
Copyright (C) Microsoft Corporation. All rights reserved.
ファイル 'ItemCard_Service.cs' に書き込んでいます。
```

- [Microsoft Docs - Creating the Web Service Proxy][23]

## 参考リンク

- [Wikipedia - SOAP (プロトコル)][01]
- [Wikipedia - WSDL ウィズダル][02]
- [GitHub - WCF Web Service Reference Provider - Release Notes][03]


[1]: #1-postman-で-web-サービスを確認する
[2]: #2-wcf-クライアント-プロキシ-コードを作成する
[01]: https://ja.wikipedia.org/wiki/SOAP_(%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB)
[02]: https://ja.wikipedia.org/wiki/Web_Services_Description_Language
[03]: https://github.com/dotnet/wcf/blob/master/release-notes/WCF-Web-Service-Reference-notes.md
[04]: https://github.com/dotnet/wcf
[05]: https://docs.microsoft.com/archive/msdn-magazine/2019/july/csharp-net-reunified-microsoft%E2%80%99s-plans-for-net-5#whats-not-in-net-5
[21]: https://docs.microsoft.com/ja-jp/dotnet/core/additional-tools/wcf-web-service-reference-guide
[22]: https://docs.microsoft.com/ja-jp/visualstudio/data-tools/how-to-add-update-or-remove-a-wcf-data-service-reference
[23]: https://docs.microsoft.com/sql/reporting-services/report-server-web-service/net-framework/creating-the-web-service-proxy