HOWTO · Csharp

C# で SOAP サービスを作成する

この記事では、SOAP クライアントとは何か、および C# で SOAP サービスを作成する方法について学習します。

このページの内容

ASP.NET Core で SOAP または WCF を利用したいのは、あなただけではありません。これは、.NETCore で最も望まれ求められている機能の 1つです。

この記事では、.NETCore アプリケーションから WCFSOAP サービスを使用する方法について説明します。また、ASP.NETCore を使用して SOAP サービスを確立およびホストする方法についても説明します。

SOAP の簡単な説明

SOAP(Simple Object Access Protocol)は、分散した、おそらく多様なシステム間で構造化データを転送するためのプロトコルです。その通信形式は XML であり、HTTP などのアプリケーション層プロトコルに依存しています。

大多数の人々は、オンラインサービスの標準プロトコルとしてそれをよく知っています。

最近まで、SOAP は Web サービスを構築するための事実上の標準であり、Service Oriented Architecture(SOA)はそれに強く依存していました。SOAP は、従う必要のあるメッセージ形式を確立しますが、その中に必要なものを自由に含めることができます。バイナリ添付ファイルも使用できます。

SOAP 標準は、含まれるエンベロープ(envelope >)を提供します。これには、ヘッダー(header >)と本体(body >)を含めることができ、後者には障害セクション(fault >)を含めることができます。他のサブセクションと同様に。body > のみが必要であり、fault > は、エラーが発生した要求ではなく、応答用に予約されています。

メッセージ中にバイナリマテリアルの一部を組み込む機能は、メッセージ送信最適化メカニズム(MTOM)と呼ばれ、Base-64 を使用してバイナリストリームをエンコードする代わりに、30%大きくなります。

SOAP Web サービス

オンラインサービスを呼び出す場合、本文には、実行するアクションと提供される可能性のある引数を含める必要があります。POST は常に SOAP Web サービスによって使用され、エンベロープは常にペイロードとして単一の既知の URL に送信されます。

Web サービスフレームワークは、要求を特定のシステムクラスおよび関数にルーティングします。

Web サービスは、各アクションメソッドの名前、それぞれの引数と戻り値、予想されるエラーなど、サービスに関する情報を含む Web サービス定義言語(WSDL)ファイルを利用できるようにします。Visual Studio(および SVCUtil.exe コマンドラインプログラムなどの他のツール)は、この WSDL を使用して Web サービスとインターフェイスするコードプロキシを生成できます。

C# の.NET コアを使用して SOAP サービスを呼び出す

その結果、.NET Core を使用してクライアント側で WCF を利用したい場合は、それが可能です。まず、System.ServiceModel が含まれていることを再確認します。

システムのプリミティブの 1つ ServiceModel.Http またはシステム(BasicHttpBinding/BasicHttpsBinding または NetHttpBinding/NetHttpsBinding バインディングの場合、SOAP と REST を含みます)。ServiceModel.NetTcp は、送受信を可能にするプロトコルです(NetTcpBinding の場合、Windows のみのバイナリプロトコル)。

基本的な例を見てみましょう。

まず、契約:

public interface IPServ {
  string P(string msg);
}

次に、クライアントコード:

var bind = new BasicHttpBinding();
var endp = new EndpointAddress(new Uri("[url]"));
var cF = new ChannelFactory(bind, endp);
var servC = cF.CreateChannel();
var res = servC.Ping("Ping");
cF.Close();

ご覧のとおり、すべてが完全な.NET フレームワークで作業している場合と同じです。App.config または Web.config ファイルがないため、正しいバインディングやエンドポイントアドレスの作成など、すべてを手動で構成する必要があります。

svcutil.exe プログラムを使用して、.NETCore 互換のプロキシクラスを手動で生成することもできます。これにより、.NETCore を使用できるようになります。

簡単さを考えると、SOAP を使用して ASP.NET Core を構成することがどれほど難しいかを見落とすのは簡単です。

C# で SoapClientMessage クラスを使用する

XML Web サービスクライアントによって送受信される SOAP メッセージを記録する SOAP 拡張機能には、次のコードセグメントが含まれます。SoapExtension に送信された SoapClientMessage は、このフラグメントによって処理されます。

SOAP 拡張機能の ProcessMessage 関数は、SoapClientMessage プロパティをログファイルに書き込みます。

// Process the SOAP message received and write it to a log file.
public override void PM(SoapMessage m) {
  switch (m.Stage) {
    case SoapMessageStage.BeforeSerialize:
      break;
    case SoapMessageStage.AfterSerialize:
      WriteOutput((SoapClientMessage)m);
      break;
    case SoapMessageStage.BeforeDeserialize:
      WriteInput((SoapClientMessage)m);
      break;
    case SoapMessageStage.AfterDeserialize:
      break;
    default:
      throw new Exception("this is and invalid state");
  }
}

出力するために、ファイルへの発信 SOAP メッセージのログはログファイルと呼ばれます。

public void WO(SoapClientMessage m) {
  newStream.Position = 0;
  FileStream mf = new FileStream(filename, FileMode.Append, FileAccess.Write);
  StreamWriter ms = new StreamWriter(mf);
  ms.WriteLine("--> Requested at " + DateTime.Now);

  // Print to the log file the  field of request header for header SoapAction .
  ms.WriteLine("The  Http SoapAction  header request field is: ");
  ms.WriteLine("\t" + m.Action);

  // Write the client type that called the XML Web service method to the log file.
  ms.WriteLine("The client type is: ");
  if ((m.Client.GetType()).Equals(typeof(MathSvc)))
    ms.WriteLine("\tMathSvc");

  // The client's technique will be printed to the log file.
  ms.WriteLine("The approach that the client has requested is:");
  ms.WriteLine("\t" + m.MethodInfo.Name);

  // The client's technique will be printed on the log file.
  if (m.OneWay)
    ms.WriteLine("The client does not wait for the server to complete the task.");
  else
    ms.WriteLine("The client waits for the server to complete the task.");

  // The URL of the site that implements the method is printed to the log file.
  ms.WriteLine("The XML Web service method that has been requested has the following URL: ");
  ms.WriteLine("\t" + m.Url);
  ms.WriteLine("The SOAP envelope's contents are as follows: ");
  ms.Flush();

  // Copy one stream's content to another.
  Copy(newStream, mf);
  mf.Close();
  newStream.Position = 0;

  // Copy one stream's content to another.
  Copy(newStream, oldStream);
}

C# で ASP.NET コアを使用して SOAP サービスを作成する

たとえば、クライアント側では、前に示したのと同じクラスを使用できます。サーバー側でコントラクトを実装するサービスクラスを開発する必要があります。

public class SS : IPServ {
  public string P(string m) {
    return string.Join(string.Empty, m.Reverse());
  }
}

そして、今やらなければならないのは、次のアドレスでサービス実装を登録することだけです。

public void ConfigServ(IServColl s) {
  s.AddSingleton(new PingService());
  s.AddMvc();
  // rest code goes here
}
public void Conf(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
  app.UseSoapEndpoint(path: "/PingService.svc", binding: new BasicHttpBinding());
  app.UseMvc();
  // rest code goes here
}

カスタムの例外から文字列への変換を実装して、発生するはずの例外から意味のあるメッセージを抽出し、必要に応じて障害文字列としてクライアントに提供できます。

s.AddSoapExceptionTransformer((ex) = > ex.Message);

このコードは、カスタムミドルウェアを ASP.NET コアパイプラインに挿入します。ASP.NET コアパイプラインは、HTTP POST をリッスンし、有効なヘッダーをチェックします。指定された実装クラスに転送する前に、ペイロードからアクションメソッドとパラメーターを抽出します。

考慮すべきいくつかのポイント

  1. .svc 拡張子は必要ありません。WCF が以前はそれを必要としていたことを私たちに思い出させるためだけにあります。
  2. PingService の場合、シングルトンだけでなく、任意のライフサイクルを利用できます。
  3. クライアントとサーバーのバインディングは同じである必要があります。
  4. ASP.NET Core フィルターは無視されるため、使用できなくなりますが、代わりに依存関係インジェクションを使用できます。

後方互換性のためにこのコードを使用することは確かですが、.NET Core で SOAP サービスを作成する必要がある場合(たとえば、Docker にデプロイする必要がある場合)は、次の制約に注意してください。

  1. WS-*標準はサポートされていません。
  2. MTOM はサポートされていません。
  3. HTTPS と ASP.NETCore の組み込みセキュリティを除き、セキュリティはサポートされていません。
  4. スロットルや不適切な動作はありません。