.net core 3.1 から SOAP 1.2 WCF サービスを利用しようとしています。
.net Framework 4のクライアントが動作しています。セキュリティ モード TransportWithMessageCredential で wsHttpBinding を使用します。
最初に、.net core クライアントで wsHttpBinding を使用しようとしましたが、「プラットフォームがサポートされていません」というメッセージが表示されました。例外。そこで、BasicHttpsBinding に切り替えましたが、関数を呼び出すときに別の例外が発生しました。
ProtocolException: コンテンツ タイプ text/xml; charset=utf-8 はサービス https://domain/Service.svc ではサポートされていませんでした。クライアントとサービスのバインディングが一致していない可能性があります。
私が見つけたところによると、BasicHttpsBinding は Soap 1.1 用であり、wsHttpBinding は Soap 1.2 用です。
そこで、https://stackoverflow.com/a/53336689に従ってSoapバージョンを1.2に設定しようとしましたが、それは私に与えました別の例外:
SocketException: 既存の接続はリモート ホストによって強制的に閉じられました。
これは .net 4 の動作設定です (読みやすくするために多少省略されています)。
<bindings>
<wsHttpBinding>
<binding name="ServiceEndpoint"
messageEncoding="Text" textEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
これは私の .net コア コードです (動作しません):
var binding = new BasicHttpsBinding();
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
binding.Security.Mode = BasicHttpsSecurityMode.TransportWithMessageCredential;
// Code from https://stackoverflow.com/a/53336689
var customTransportSecurityBinding = new CustomBinding(binding);
var textBindingElement = new TextMessageEncodingBindingElement
{
MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None)
};
// Replace text element to have Soap12 message version
customTransportSecurityBinding.Elements[1] = textBindingElement;
var serviceClient = new Svc.ServiceClient(customTransportSecurityBinding, new EndpointAddress("https://domain/Service.svc"));
serviceClient.ClientCredentials.UserName.UserName = "usr";
serviceClient.ClientCredentials.UserName.Password = "pwd";
var units = serviceClient.GetUnitsAsync().Result; // Exception here
------------------------
サーバーとクライアントは、同じバインディングを使用して通信する必要があります。サーバーは wsHttpBinding を使用しますが、クライアントは BasicHttpsBinding を使用するため、正常に通信できません。
その通りです。 Core は現在 wsHttpBinding をサポートしていないため、解決策は 2 つあります。
1:サーバーの wsHttpBinding を BasicHttpBinding に変更し、tこのコアはメッセージ セキュリティ モードをサポートしていません。コアの WCF 機能については、以下のリンクを参照してください。
https://github.com/dotnet/wcf/blob/master/release-notes/SupportedFunctions-v2.1.0.md
2:クライアントはコアの代わりに .net フレームワークを使用します。
2 番目の解決策を使用することをお勧めします。結局のところ、コアの wcf サポートは良くありません。
問題が解決しない場合は、お気軽にお知らせください。
2
愚かな質問ですが、そもそも WCF が .Net コアから呼び出すのはなぜでしょうか?これはすべて単純な H を使用して実行できます。ttpClient POST 呼び出し。リクエストの応答をシリアル化/逆シリアル化する必要がありますが、XSD または多くのオンライン ツールの 1 つを使用して必要なクラスを作成することで簡単に行うことができます。私も古い WCF クライアントを .net core に移植したときに同様の状況に陥り、最終的に HttpClient ルートを選択することになりました。よりシンプルで、より高速とも言えます。
– シーマ フォー
2020 年 9 月 4 日 3:08
@CeemahFour そうですね、「すぐに」動作させる方法があるとしたら、 (ws を使用した .net Framework と同様)HttpsBinding) の場合、VS がすべてのコードを生成してくれるため、(少なくとも私にとっては) 高速になります :) しかし、.net core の方法を使用したい場合の解決策としてもこれを考えました。ご意見ありがとうございます。
– Björn
2020 年 9 月 4 日 5:52