通信オブジェクトSystem.ServiceModel.Channels.ServiceChannelは通信に使用できません


156

通信オブジェクトSystem.ServiceModel.Channels.ServiceChannelは、Faulted状態であるため、通信に使用できません。

このエラーとは何ですか?それを解決するにはどうすればよいですか?

回答:


151

このエラーが発生するのは、サーバー側で.NET例外を発生させ、それをキャッチして処理せず、SOAPフォールトに変換しなかったためです。

サーバー側が「爆撃」されたため、WCFランタイムがチャネルに「障害」を起こしました。たとえば、クライアントとサーバー間の通信リンクが使用できなくなります-結局のところ、サーバーが故障したように見えるため、通信できませんそれ以上。

だからあなたがする必要があるのは:

  • 常にサーバー側のエラーをキャッチして処理します。.NETの例外がサーバーからクライアントに伝わらないようにしてください。それらは常に相互運用可能なSOAPエラーにラップされます。WCF IErrorHandlerインターフェイスを確認し、サーバー側で実装する

  • クライアントから2番目のメッセージをチャネルに送信する場合は、チャネルがフォルト状態になっていないことを確認してください。

    if(client.InnerChannel.State != System.ServiceModel.CommunicationState.Faulted)
    {
       // call service - everything's fine
    }
    else
    {
       // channel faulted - re-create your client and then try again
    }
    

    もしそうなら、あなたができることはそれを処分し、クライアント側のプロキシを再作成してからもう一度試すことです


11
問題がクライアント側にある場合も同じエラーが発生する可能性があります。たとえば、受信メッセージのメッセージサイズクォータを超えた場合などです。
1

6
クライアントを再作成するにはどうすればよいですか?
Masoud 2015

32

サーバーが障害状態になるのを防ぐには、未処理の例外が発生しないようにする必要があります。WCFが予期しない例外を検出した場合、それ以上の呼び出しは受け入れられません-安全第一。
この動作を回避する2つの可能性:


  1. 代わりに 、FaultExceptionを使用します(これはWCFにとって予期しないものではないため、WCFはサーバーがまだ有効な状態であることを認識しています)。

    throw new Exception("Error xy in my function")  

    いつも使う

    throw new FaultException("Error xy in my function")  

    おそらく、ブロック全体をキャッチして、例外のすべてのケースでFaultExceptionをスローすることができます。

    try   
    {  
        ... some code here   
    }
    catch (Exception ex)
    {  
        throw new FaultException(ex.Message)   
    }
    
  2. Errorhandlerを使用してすべての例外を処理するようにWCFに指示します。これはいくつかの方法で実行できます。属性を使用して簡単な方法を選択しました。必要なサービス実装で
    属性を使用するだけです。[SvcErrorHandlerBehaviour]

    using System;
    using System.Collections.ObjectModel;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Description;
    using System.ServiceModel.Dispatcher;
    
    namespace MainService.Services
    {
        /// <summary>
        /// Provides FaultExceptions for all Methods Calls of a Service that fails with an Exception
        /// </summary>
        public class SvcErrorHandlerBehaviourAttribute : Attribute, IServiceBehavior
        {
            public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
            { } //implementation not needed
    
            public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints,
                                             BindingParameterCollection bindingParameters)
            { } //implementation not needed
    
            public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
            {
                foreach (ChannelDispatcherBase chanDispBase in serviceHostBase.ChannelDispatchers)
                {
                    ChannelDispatcher channelDispatcher = chanDispBase as ChannelDispatcher;
                    if (channelDispatcher == null)
                        continue;
                    channelDispatcher.ErrorHandlers.Add(new SvcErrorHandler());
                }
            }
        }
    
        public class SvcErrorHandler: IErrorHandler
        {
            public bool HandleError(Exception error)
            {
                //You can log th message if you want.
                return true;
            }
    
            public void ProvideFault(Exception error, MessageVersion version, ref Message msg)
            {
                if (error is FaultException)
                    return;
    
                FaultException faultException = new FaultException(error.Message);
                MessageFault messageFault = faultException.CreateMessageFault();
                msg = Message.CreateMessage(version, messageFault, faultException.Action);
            }
        }
    }
    

これは簡単な例です。nakedを使用せずにIErrorhandlerをさらに詳しく調べることができますFaultExceptionが、FaultException<>追加情報を提供する型を使用して、詳細な例についてIErrorHandlerを参照してください。


10

実際のところ、marc_sの提案に従っても失敗した場合、サーバーのweb.configのサーバーバインディング構成の<security>要素(またはその欠如)がこの例外を引き起こす可能性があることに注意してください。たとえば、サーバーは- Messageレベルのセキュリティを想定しており、クライアントはに設定されていますNone(または、サーバーがActive Directoryドメインの一部ではなく、リモートクライアントホストの一部である場合)。

ヒント:このような場合、RDPセッションの管理者アカウントでサーバーマシン上で直接実行すると、クライアントアプリがWebサービスを正常に呼び出す可能性があります。


2

この問題を診断するには、Visual Studioデバッガーでサービスを実行します。[デバッグ|例外]メニューを使用して、例外がスローされたときに中断することを指定します。

スローされた元の例外には、「..障害状態です」よりもはるかに優れたエラーメッセージが表示されます。

たとえば、ServiceHost.Open()からこの例外を取得していましたが、スローされたときに元の例外をキャッチすると、エラーメッセージは次のようになりました。

サービス「MyServiceName」には、アプリケーション(インフラストラクチャでない)エンドポイントがありません。これは、アプリケーションの構成ファイルが見つからなかったか、構成ファイルでサービス名と一致するサービス要素が見つからなかったか、サービス要素でエンドポイントが定義されていなかったことが原因である可能性があります。

App.configのスペルミスを修正することで問題は解決しました。


VS2015で[デバッグ]→[例外設定]を選択し、[共通言語ランタイム例外]を選択します。
SharpC 2018年

1
では、Visual Studioデバッガーを使用するまで、なぜ元の例外が与えられなかったのでしょうか。
Jez

2

http asmxサービスでnet.tcp wcfサービスエンドポイントを使用しようとしたときに、同じ問題が発生しました。

誰も特定の答えを書いていないのを見たので、なぜこの問題が発生したのかではなく、適切に処理する方法だけです。

私は数日続けてそれと格闘していました、そして最後に私は私の問題のどこから問題が発生しているのかを見つけました。

最初に、サービスへの参照を作成すると、セキュリティタグに関してソース内と同じように構成ファイルが構成されると思いましたが、そうではなかったので、手動で処理する必要があります。私の場合、私は

<netTcpBinding>
    <binding name="NetTcpBinding_IAuthenticationLoggerService"
    </binding>
</netTcpBinding>`

後でセキュリティ部分が欠落していることがわかりました。これは次のようになります。

<netTcpBinding>
    <binding name="NetTcpBinding_IAuthenticationLoggerService" transferMode="Buffered">
      <security mode="None">
        <transport clientCredentialType="None"/>
      </security>
    </binding>
  </netTcpBinding>

私の場合の2番目の問題は、transferMode="Streamed"ソースWCFサービスで使用していて、クライアントでは何も特定していなかったということです。これは、デフォルトでtransferModeありBuffered、ソースとクライアントの両方で同じように構成することが重要であるためです。仕方。


1

他の回答では言及されていないと思う別の問題がありました。

同じTCPアドレスとポートのエンドポイントにサービスを提供する必要があります。app.configで、両方のエンドポイントを追加するのを忘れていたため、サービスは正しいポートで実行されていましたが、サービスインターフェースが間違っていました。


1

Visual Studioからのデバッグでこのメッセージが表示され、ソリューションにWCFプロジェクトが含まれている場合。次に、このWCFプロジェクト設定を開きます-> [WCFオプション]タブに移動します-> [デバッグ時にWCFサービスホストを開始...]オプションをオフにします


私は同じ問題を抱えていて、しばらくの間この問題に行き詰まりました。おそらく、同じソリューションにクライアントとサーバーの両方を配置することはお勧めできません。ありがとうございました!
yoosha 2016

1

私にとっての問題は、WSDLのインポートによって自動的に生成された構成ファイルが原因でした。バインディングをbasicHttpBindingからcustomBindingに更新しました。例外処理を追加しても、これを指摘するのに役立ちませんでした。

<basicHttpBinding>
            <binding name="ServiceName">
                <security mode="Transport" />
            </binding>
        </basicHttpBinding>`

<customBinding>
        <binding name="ServiceName">
          <textMessageEncoding messageVersion="Soap12" />
          <httpsTransport />
        </binding>
      </customBinding>`

0

私の場合、理由はロードできなかった間違った証明書でした。それについては、システムの下のイベントビューアから確認しました。

TLSサーバー資格情報の秘密鍵にアクセスしようとしたときに、致命的なエラーが発生しました。暗号化モジュールから返されたエラーコードは0x8009030Dです。内部エラー状態は10001です。


0

このエラーは、ハンドルされていない例外だけでなく、ご使用のコンピューターによってもトリガーされます。サーバー/コンピューターのクロックタイムが長すぎると、多くの.NET Webサービスが未処理のエラーでリクエストを拒否します。彼らの観点からは処理されますが、あなたの観点からは処理されません。受信サーバーの時刻が正しいことを確認してください。修正する必要がある場合は、サービスをリセットするか、チャネルを再開する前に再起動する必要があります。

ファイアウォールがインターネット時刻の更新をブロックしているサーバーでこの問題が発生し、サーバーが何らかの理由でオフタイムになりました。すべてのサードパーティの.NET Webサービスは、Webサービス要求を拒否したため、障害が発生しました。イベントビューアを掘り下げることで問題を特定することができましたが、クロックを調整することで解決しました。エラーは、将来のWebサービス呼び出しのためにFaulted Stateエラーメッセージを受信したにもかかわらず、私たちの側にありました。


0

サーバーは、受信タイムアウト(デフォルトは10分)の間、メッセージが受信されなかった接続を自動的に中止します。これは、クライアントがサーバーに無期限に接続を開かせることを防ぐためのDoS緩和策です。

サーバーはアイドル状態になったために接続を中止するため、クライアントはこの例外を受け取ります。

サーバーのバインディングで受信タイムアウトを構成することにより、サーバーが接続をアイドル状態にしてから中断するまでの時間を制御できます。クレジット:TRVishwanath-MSFT


0

私はこれが古い投稿であることを知っていますが、セキュリティを変更できない場合に注意する必要があるのは、ユーザー名とパスワードが設定されていることを確認することです。

authenticationNameがUserNameOverTransportのサービスがあり、サービスクライアントにユーザー名とパスワードが設定されていない場合、このエラーが発生しました。


0

私にとっては、ロードバランサー/ URLの問題でした。ロードバランサーの背後にあるWebサービスが、次のような完全なURLを使用して同じロードバランサーの背後にある別のサービスを呼び出しましたloadbalancer.mycompany.comlocalhost.mycompany.com代わりにを使用して2番目のサービスを呼び出すときに、ロードバランサーをバイパスするように変更しました。

ロードバランサーで何らかの循環参照の問題が発生していたと思います。


-2

この問題の解決策ではありませんが、Ektron eSyncで上記のエラーが発生する場合は、データベースのディスク領域が不足している可能性があります。

編集:実際、これは完全にEktron eSyncのみの問題ではありません。これは、データベース全体を照会するサービスで発生する可能性があります。

編集:ディスク容量不足、または必要なディレクトリへのアクセスをブロックすると、この問題が発生します。


これは質問に対する答えを提供しません。批評したり、著者に説明を要求したりするには、投稿の下にコメントを残します。自分の投稿にはいつでもコメントできます。十分な評判得られれ、どの投稿にもコメントできます。
Dariusz 2013

2
私は彼の質問に「私はそれをどのように解決しようとしますか?」と答えました、それは彼がエクトロンを使用していたかどうかの詳細を私たちに決して与えなかった私のせいではありません。彼の投稿にコメントするには、50人の担当者も必要です。
ジョナサンビック2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.