net.pipeを使用してホストとクライアントの両方が同じプロセスにあるFaultContractsをサポートするようにWCFを構成するにはどうすればよいですか?
-
03-07-2019 - |
質問
net.pipeバインディングを使用して、サービスとクライアントのやり取りのインプロセスユニットテストを作成しようとしています。優れたWCFサービスと同様に、サービス操作でFaultContractAttributeを使用して、考えられる障害(ラップされた例外)をメタデータに公開します。 XMLを介してクライアントとサービスのエンドポイントを構成したいと思います。期待していた。
System.ServiceModel.CommunicationException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d).
net.pipeにIMetadataExchangeエンドポイントを追加しようとしましたが、うまくいきませんでした。私も試しました。 Vistaにあるため、httpエンドポイントのACLをnetshする必要がありました。それもうまくいきませんでした。
カスタム例外クラス:
public class ValidationException : ApplicationException { }
これは構成の最新の試みですが、それはポンプアウトします
これを実現する方法の例や推奨事項へのリンクをいただければ幸いです。
<system.serviceModel>
<client>
<endpoint name="Client"
contract="IService"
address="net.pipe://localhost/ServiceTest/"
binding="netNamedPipeBinding"
bindingConfiguration="netPipeBindingConfig" />
</client>
<services>
<service
name="Service"
behaviorConfiguration="ServiceFaults">
<host>
<baseAddresses>
<add baseAddress="net.pipe://localhost/ServiceTest/"/>
<add baseAddress="http://localhost/ServiceTest/"/>
</baseAddresses>
</host>
<endpoint
address=""
binding="netNamedPipeBinding"
bindingConfiguration="netPipeBindingConfig"
name="ServicePipe"
contract="IService" />
<endpoint
address="MEX"
binding="mexNamedPipeBinding"
bindingConfiguration="mexNetPipeBindingConfig"
name="MexUserServicePipe"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<netNamedPipeBinding>
<binding name="netPipeBindingConfig"
closeTimeout="00:30:00"
sendTimeout="00:30:00" />
</netNamedPipeBinding>
<mexNamedPipeBinding>
<binding name="mexNetPipeBindingConfig"></binding>
</mexNamedPipeBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceFaults">
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
<behavior name="MEX">
<serviceMetadata
httpGetEnabled="true"
httpGetUrl="http://localhost/ServiceTest/MEX"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
解決
上記で説明したValidationExceptionクラスが障害に使用しているクラスである場合、それが問題の原因である可能性があります。 FaultExceptionはSerializableであるため、FaultExceptionからフォールト例外を派生させる必要があります。 ApplicationExceptionはそうではありません。
Wagnerは正しいです。FaultContract属性を使用して操作定義を修飾し、コントラクトのタイプを指定する必要があります。また、DataContract属性とDataMember属性を使用してFaultContractを装飾する必要もあります。
他のヒント
数日前に同じエラーが発生しました。
独自のクラス(MyFault)を作成し、サーバーからFaultExceptionをスローして、クライアントでそれらをキャッチすることを解決しました。 MyFaultには、クライアントに表示する例外メッセージである文字列メンバーがあります。
自分自身を明確にしたいと思います...素敵なサンプルを探して、ここに投稿します
問題は、リクエストまたはレスポンスの逆シリアル化またはシリアル化のエラーである可能性があります。トレースを有効にし、正確なエラーのsvctraceviewerでログを表示します。
また、フォールト例外が[DataContract]でマークされ、[DataContract]クラスを継承しないことを確認してください。
最後に追加すること。オペレーションコントラクトは、使用しているServiceFaultを定義していますか。
私の理解では、オペレーションレイヤーで使用しているServiceFaultを定義する必要があり、ビジネスロジックはFaulExceptionをスローします。Tは定義したServiceFaultです。