SOAP
C#
ASP.NET_Core

ASP.NET CoreでHTTP SOAPリクエストを処理する

More than 1 year has passed since last update.


始めに

SOAPとは、簡単に言うとXMLベースのRPCプロトコルフォーマットの事である。

SOAP自体はもっと大きい枠組みであるWeb services protocol stackの一部らしいが、単体でも利用可能なものになっている。

本来ならば、様々な通信に乗せて使用することもできるらしいが、現在の所主に使用されているのはHTTP上である。

(主に、とは書いてあるが、現在のところ各所でほぼレガシー扱いされていると思うので今後増えるかどうかは不明)

以後、特に断りが無い限り、HTTP上で利用されるSOAP通信の事を書く。


.NET Frameworkあるいはmonoでの利用

.NET Frameworkは、サーバー、クライアント双方のライブラリが用意されている。monoでも、ドキュメントを見る限り、基本的な部分は使用する分には問題なく使えそう(WCFは未検証、ASMXは機能的にはほぼ使える)


サーバー側

C#でSOAPリクエストのサービスを提供する場合、ASP.NET XML Web Service(ASMX)を使用するか、WCFを使用することになる。どちらかというと、ASMXの方が古い。


クライアント側

クライアントの場合は、WCFのクライアントライブラリを使用するか、WSDL.exeコマンドでクライアントを生成することで、SOAP通信を利用することができる。

どちらもWindows SDKに入っているはず。


何が問題か

上で記述したのは.NET Frameworkの話である。では、.NET Coreはどうなのか、というと、クライアントは問題ない。

厳密に検証したわけではないが、WCFのnugetパッケージを利用すれば、クライアント部分はほぼ問題なく使える模様。

しかし、サーバー部分の提供は無い。SOAP自体がほぼレガシーになっている現在、ASP.NET Coreの方で正式サポートしないのは仕方ない話である。しようと思うとどうしても重厚長大になるだろうし。

では現状維持のままでいいかというと、ASP.NET Coreには既存のASP.NETにはない新機能や、パフォーマンスアップ等が推し進められており、サーバーサイドとしてはどうしても移行したい。

全体は新しいやり方に移行するにしても、古いクライアントを対象に互換レイヤーを提供しなければならない場合もあるので、どうしてもここが移行の障害となる。


解決策

元々SOAP自体は単なるプロトコルなので、そのアクセスを受け付けるようにすればいいという話となる。

そして、正式サポートされていないならば、自分で作るか、あるいはサードパーティーのライブラリを使えば良い。

ということで紹介するのが SoapCoreである。


サービス実装方法


一から作る場合

asp.net coreプロジェクト自体の用意は ASP.NET Coreのドキュメントを参考にして、予め構築しているものとする。



  1. System.ServiceModel.ServiceContractAttributeを追加したインターフェイスを作成する

  2. メソッドにSystem.ServiceModel.OperationContractAttributeを追加する


    • refやoutも使用可能



  3. インターフェイスの実装クラスを作成する

  4. StartupクラスのConfigureServicesで、実装クラスをTryAddSingletonで追加する

  5. StartupクラスのConfigureで、UseSoapEndpointで、エントリポイントを追加する




WCFからの移行

定義等はほとんどそのままで移行可能。async Taskメソッドも使える。ただし、IAsyncResultを利用した非同期メソッドは使えない。基本的にWCFの機能はほとんど移行されていないため、どちらにしろ検証は必要。


ASMXからの移行

ASMXから移行する場合は少々面倒な手順が必要。まず、System.Webに大きく依存しているため、WCFのように定義をそのまま移行というわけにはいかない。

メソッドの定義等は、WSDLからsvcutil.exeでスケルトンを作ることは可能。(Windows SDKに入っている)

また、WSDL.exeからサーバーインターフェイスコードを生成し、そこから属性の付け替えを行うという手もある。

既にインターフェイスとして分離しているならば、そこから属性の付け替えでも移行が可能。(WebServiceBindingAttributeからServiceContractAttributeSoapDocuemntMethodAttributeWebMethodAttributeからOperationContractAttribute)

なお、HttpContextは使えないので、実装クラスでは注意すること。


注意点


XML名前空間について

SOAPではXML名前空間を使用しているので、ここはクライアントとサーバー間で合わせる必要がある。具体的には ServiceContractAttributeNamespaceと、また、OperationContractAttributeNamespaceがそれになる。


SOAPバージョンについて

現在使われているSOAPは1.1と1.2の2系統がある。1.1は問題なく処理可能だが、SoapCoreの0.9.6では、まだSOAP1.2メッセージは処理できないので注意。masterには修正がマージされているので、次のバージョンでは処理できるようになるかもしれない。

0.9.7よりパースできるようになりました。

SOAPバージョンについての参考URL: https://www.ibm.com/support/knowledgecenter/ja/SSAW57_8.5.5/com.ibm.websphere.nd.doc/ae/cwbs_soapverdiffs.html


終りに

SOAPリクエストを処理できるようになるというだけなので、WCFやASMXのコードがそのまま移行できるわけではないということに注意。あくまでも移行のための互換レイヤーとみて、過度な期待はしない方がいい。フォーマットにXMLを使用している以上、grpc等に処理速度では勝てないだろうし。

非機能面は厳密には計測していない。中身を見ると、リクエストの振り分け時にリフレクションを使用しているので、もしかしたら劣る可能性もなくはない。この辺りの計測は今後の宿題となりそう。