.net 4.6.2コードをSOAPサービスを呼び出す。netコアプロジェクトに移植しています。新しいコードでは、C#を使用しています(設定上の理由により、今はなぜなのか思い出せません)。
しかし、次の例外が発生しています。
https://someurl.com/ws/Thing.pub.ws:Something へのHTTP応答の受信中にエラーが発生しました。これは、サービスエンドポイントバインディングがHTTPプロトコルを使用していないことが原因である可能性があります。これは、サーバーによって中断されたHTTP要求コンテキストが原因である可能性もあります(おそらくサービスのシャットダウンが原因です)。詳細については、サーバーログを参照してください。
それを投げているコードは
try
{
var binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
var endpoint = new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService"));
var thing= new TheEndpoint.AService_PortTypeClient(binding, endpoint);
thing.ClientCredentials.UserName.UserName = "usrn";
thing.ClientCredentials.UserName.Password = "passw";
var response = await thing.getSomethingAsync("id").ConfigureAwait(false);
}
finally
{
await thing.CloseAsync().ConfigureAwait(false);
}
サービスを呼び出して動作する古い構成に基づいて、このようなものです私は何が欠けていますか?
<bindings>
<basicHttpsBinding>
<binding name="TheEndpoint_pub_ws_AService_Binder" closeTimeout="00:02:00"
openTimeout="00:02:00" receiveTimeout="00:03:00" sendTimeout="00:03:00">
<security mode="Transport">
<transport clientCredentialType="Basic" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpsBinding>
</bindings>
<client>
<endpoint address="https://someurl.com/ws/Thing.pub.ws:AService"
binding="basicHttpsBinding" bindingConfiguration="TheEndpoint_pub_ws_AService_Binder"
contract="TheEndpoint.AService_PortType" name="TheEndpoint_pub_ws_AService_Port" />
</client>
このオンラインで多くの情報を見つけることができません。あなたが私を助けることができることを願っています。
UPDATESixto Saezの提案に従って、エンドポイントにエラーを明らかにしてもらいました。
HTTP要求は、クライアント認証スキーム「基本」で許可されていません。サーバーから受信した認証ヘッダーは、 'Basic realm = "Integration Server"、encoding = "UTF-8"'でした。
何をすべきかを見つけ、成功した場合はここに結果を投稿しようとします。
更新2
さて、ここでこのコードを使用して新しい構文に移動しようとしました
ChannelFactory<IAService> factory = null;
IAService serviceProxy = null;
Binding binding = null;
try
{
binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
factory = new ChannelFactory<IAService>(binding, new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService")));
factory.Credentials.UserName.UserName = "usrn";
factory.Credentials.UserName.Password = "passw";
serviceProxy = factory.CreateChannel();
var result = await serviceProxy.getSomethingAsync("id").ConfigureAwait(false);
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
catch (MessageSecurityException ex)
{
//error caught here
throw;
}
しかし、私はまだ同じ(わずかに異なる)エラーを受け取ります。 「基本」ではなく「匿名」になり、最後に「、encoding = "UTF-8"がなくなりました。
HTTP要求は、クライアント認証スキーム「匿名」で許可されていません。サーバーから受信した認証ヘッダーは「Basic realm = "Integration Server"」でした。
問題は私の側にあるのか、サーバーにあるのか?
明らかに、私のSOAP "スキル"は現在、非常に不足していますが、この新しいアプローチで思いつかないすべての構成コンボを試してみました。誰かが私を正しい方向に向けてくれることを願っています。
OKこの答えは、接続しようとしている人向けですWCFへサービス。netコアからプロジェクト。
新しい.net Core WCF構文/ライブラリを使用したmy問題の解決策を次に示します。
BasicHttpBinding basicHttpBinding = null;
EndpointAddress endpointAddress = null;
ChannelFactory<IAService> factory = null;
IAService serviceProxy = null;
try
{
basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
endpointAddress = new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService"));
factory = new ChannelFactory<IAService>(basicHttpBinding, endpointAddress);
factory.Credentials.UserName.UserName = "usrn";
factory.Credentials.UserName.Password = "passw";
serviceProxy = factory.CreateChannel();
using (var scope = new OperationContextScope((IContextChannel)serviceProxy))
{
var result = await serviceProxy.getSomethingAsync("id").ConfigureAwait(false);
}
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
catch (MessageSecurityException ex)
{
throw;
}
catch (Exception ex)
{
throw;
}
finally
{
// *** ENSURE CLEANUP (this code is at the WCF GitHub page *** \\
CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
UPDATE
上記のコードを使用して次の例外が発生しました
このOperationContextScopeは順不同で破棄されています。
これは 壊れている何か (または対処が必要)のようです。
だから、私はそれを機能させるために次のことをしなければなりませんでした(これに基づいて GitHub問題 )
basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
factory = new ChannelFactory<IAService_PortType>(basicHttpBinding, new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService")));
factory.Credentials.UserName.UserName = "usern";
factory.Credentials.UserName.Password = "passw";
serviceProxy = factory.CreateChannel();
((ICommunicationObject)serviceProxy).Open();
var opContext = new OperationContext((IClientChannel)serviceProxy);
var prevOpContext = OperationContext.Current; // Optional if there's no way this might already be set
OperationContext.Current = opContext;
try
{
var result = await serviceProxy.getSomethingAsync("id").ConfigureAwait(false);
// cleanup
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
finally
{
// *** ENSURE CLEANUP *** \\
CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
OperationContext.Current = prevOpContext; // Or set to null if you didn't capture the previous context
}
ただし、要件はおそらく異なるでしょう。 WCFサービスへの接続に役立つリソースは次のとおりです。
テストは私を大いに助けてくれましたが、見つけるのが少し難しい場所でした(助けがありました、Zhenlanに感謝します 私のwcf githubの問題に答えます )
.NETコアからSOAPサービスを使用するために、プロジェクトUIから接続されたサービスを追加しても機能しません。
オプション1:dotnet-svcutil CLIを使用します。前提条件:VS 2017、バージョン15.5以降
App.csprojファイルに移動して、以下の参照を追加します。
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
<PackageReference Include="System.ServiceModel.Http" Version="4.5.3" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="dotnet-svcutil" Version="1.0.*" />
</ItemGroup>
ソリューションを再構築します。
オプション2複数のSOAPサービスを参照する必要がある場合
NTLMと.Net Coreで同じことをしようとしていて、いくつかの変数がどのように定義されているのか疑問に思っている人のために、コードを次のように明確にしました。
IAService_PortType
は、 https://joshuachini.com/2017/07/13/calling-a-soap-service-from-asp-net-coreのガイドに従って作成したサービス参照です。 -or-net-core /
BasicHttpBinding basicHttpBinding =
new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
// Setting it to Transport will give an exception if the url is not https
basicHttpBinding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Ntlm;
ChannelFactory<IAService_PortType> factory =
new ChannelFactory<IAService_PortType>(basicHttpBinding,
new EndpointAddress(
new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService")));
factory.Credentials.Windows.ClientCredential.Domain = domain;
factory.Credentials.Windows.ClientCredential.UserName = user;
factory.Credentials.Windows.ClientCredential.Password = pass;
IAService_PortType serviceProxy = factory.CreateChannel();
((ICommunicationObject)serviceProxy).Open();
try
{
var result = serviceProxy.getSomethingAsync("id").Result;
}
finally
{
// cleanup
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
そのため、これを行う必要があり、 WCF Webサービス参照プロバイダーツール を使用しました。
ここにあるような回答によると、Bindings and Factories and Proxiesとのすべてのラウンドアバウトビジネスに対する明らかな必要性は奇妙なようでした。
簡単な公式の「HowTo」が見つからないので、要件に合わせてまとめたsimplestセットアップに関する調査結果を投稿しますダイジェスト認証の場合:
ServiceName_PortClient client = new ServiceName_PortClient();
//GetBindingForEndpoint returns a BasicHttpBinding
var httpBinding = client.Endpoint.Binding as BasicHttpBinding;
httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Digest;
client.ClientCredentials.HttpDigest.ClientCredential = new NetworkCredential("Username", "Password", "Digest");
var result = await client.GetResultAsync();
ここで、単に認証を行う必要がない場合:
ServiceName_PortClient client = new ServiceName_PortClient();
var result = await client.GetResultAsync();
十分なはずです。
ServiceName_PortClient
クラスは、インポートツールによってそのように生成されました。ServiceName
は、インポートするサービスの名前です。
もちろん、次の行に沿って部分的なServiceName_PortClient
クラスに設定を配置することは、インポートされたコードの精神にあるようです。
public partial class ServiceName_PortClient
{
static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials)
{
var httpBinding = serviceEndpoint.Binding as BasicHttpBinding;
httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Digest;
clientCredentials.HttpDigest.ClientCredential = new NetworkCredential("Username", "Password", "Realm");
}
}