このトピックでは、WCF クライアントとサービスの開発中に発生した既知の問題の一覧を示します。 実行している問題がこの一覧にない場合は、サービスのトレースを構成することをお勧めします。 これにより、トレース ファイル ビューアーで表示できるトレース ファイルが生成され、サービス内で発生している可能性がある例外に関する詳細情報を取得できます。 トレースの構成の詳細については、「トレースの 構成」を参照してください。 トレース ファイル ビューアーの詳細については、「 サービス トレース ビューアー ツール (SvcTraceViewer.exe)」を参照してください。
Windows 7 と IIS をインストールした後、WCF サービスを参照しようとすると、次のエラー メッセージが表示されます:HTTP エラー 404.3 – 見つかりません
HTTP エラー 404.3 – Not Found 要求しているページは、拡張機能の構成のために提供できません。 ページがスクリプトの場合は、ハンドラーを追加します。 ファイルをダウンロードする必要がある場合は、MIME マップを追加します。 詳細なエラー情報モジュール StaticFileModule。
クライアントが最初の要求の後しばらくアイドル状態の場合、2 番目の要求で MessageSecurityException を受け取ることがあります。 どうしたんですか。
約 10 個のクライアントがクライアントとやり取りした後、サービスが新しいクライアントを拒否し始めます。 どうしたんですか。
サービスとクライアントはうまく機能しますが、クライアントが別のコンピューター上にある場合は機能しませんか? どうしたんですか。
サービスで X.509 証明書を使用していて、System.Security.Cryptography.CryptographicException を取得します。 どうしたんですか。
操作の最初のパラメーターを大文字から小文字に変更しました。クライアントが例外をスローするようになりました。 どうしてでしょうか。
トレース ツールの 1 つを使用していて、EndpointNotFoundException を取得します。 どうしたんですか。
WCF SOAP アプリケーションから WCF Web HTTP アプリケーションを呼び出すと、サービスは次のエラーを返します。
ベース アドレスは何ですか? エンドポイント アドレスとどのように関連していますか?
Windows 7 と IIS をインストールした後、WCF サービスを参照しようとすると、次のエラー メッセージが表示されます:HTTP エラー 404.3 – 見つかりません
エラー メッセージの全文は次のとおりです。
HTTP エラー 404.3 – Not Found 要求しているページは、拡張機能の構成のために提供できません。 ページがスクリプトの場合は、ハンドラーを追加します。 ファイルをダウンロードする必要がある場合は、MIME マップを追加します。 詳細なエラー情報モジュール StaticFileModule。
このエラー メッセージは、コントロール パネルで "Windows Communication Foundation HTTP アクティブ化" が明示的に設定されていない場合に発生します。 これを設定するには、[コントロール パネル] に移動し、ウィンドウの左下隅にある [プログラム] をクリックします。 [Windows の機能をオンまたはオフにする] をクリックします。 Microsoft .NET Framework 3.5.1 を展開し、Windows Communication Foundation HTTP ライセンス認証を選択します。
クライアントが最初の要求の後しばらくアイドル状態の場合、2 番目の要求で MessageSecurityException を受け取ることがあります。 どうしたんですか。
2 番目の要求は、主に 2 つの理由で失敗する可能性があります。(1) セッションがタイムアウトしたか、(2) サービスをホストしている Web サーバーがリサイクルされます。 最初のケースでは、セッションはサービスがタイムアウトするまで有効です。サービスのバインディング (ReceiveTimeout) で指定された時間内にサービスがクライアントから要求を受信しない場合、サービスはセキュリティ セッションを終了します。 後続のクライアント メッセージは、 MessageSecurityExceptionになります。 クライアントは、将来のメッセージを送信したり、ステートフル セキュリティ コンテキスト トークンを使用したりするために、サービスとのセキュリティで保護されたセッションを再確立する必要があります。 ステートフル セキュリティ コンテキスト トークンを使用すると、セキュリティで保護されたセッションでも、リサイクルされる Web サーバーを存続できます。 セキュリティで保護されたセッションでステートフル セキュリティ コンテキスト トークンを使用する方法の詳細については、「 方法: セキュリティで保護されたセッションのセキュリティ コンテキスト トークンを作成する」を参照してください。 または、セキュリティで保護されたセッションを無効にすることもできます。
<wsHttpBinding> バインドを使用する場合は、セキュリティで保護されたセッションを無効にするために、establishSecurityContext
プロパティをfalse
に設定できます。 他のバインドのセキュリティで保護されたセッションを無効にするには、カスタム バインドを作成する必要があります。 カスタム バインドの作成の詳細については、「 方法: SecurityBindingElement を使用してカスタム バインドを作成する」を参照してください。 これらのオプションのいずれかを適用する前に、アプリケーションのセキュリティ要件を理解しておく必要があります。
約 10 個のクライアントがクライアントとやり取りした後、サービスが新しいクライアントを拒否し始めます。 どうしたんですか。
既定では、サービスの同時セッション数は 10 個のみです。 そのため、サービス バインドでセッションが使用されている場合、サービスはその数に達するまで新しいクライアント接続を受け入れ、その後、現在のセッションのいずれかが終了するまで新しいクライアント接続を拒否します。 さまざまな方法でより多くのクライアントをサポートできます。 サービスにセッションが必要ない場合は、セッションフル バインディングを使用しないでください。 (詳細については、「セッションの 使用」を参照してください)。もう 1 つのオプションは、 MaxConcurrentSessions プロパティの値を状況に適した数に変更して、セッションの制限を増やすことです。
WCF アプリケーションの構成ファイル以外の場所からサービス構成を読み込むことができますか?
はい。ただし、ApplyConfiguration メソッドをオーバーライドするカスタム ServiceHost クラスを作成する必要があります。 そのメソッド内では、最初にベースを呼び出して構成を読み込むことができます (標準の構成情報も読み込む場合) が、構成読み込みシステムを完全に置き換えることができます。 アプリケーション構成ファイルとは異なる構成ファイルから構成を読み込む場合は、構成ファイルを自分で解析して構成を読み込む必要があります。
次のコード例は、 ApplyConfiguration メソッドをオーバーライドし、エンドポイントを直接構成する方法を示しています。
public class MyServiceHost : ServiceHost
{
public MyServiceHost(Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
Console.WriteLine("MyServiceHost Constructor");
}
protected override void ApplyConfiguration()
{
string straddress = GetAddress();
Uri address = new Uri(straddress);
Binding binding = GetBinding();
base.AddServiceEndpoint(typeof(IData), binding, address);
}
string GetAddress()
{
return "http://MyMachine:7777/MyEndpointAddress/";
}
Binding GetBinding()
{
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.None;
return binding;
}
}
サービスとクライアントはうまく機能しますが、クライアントが別のコンピューター上にある場合は機能しませんか? どうしたんですか。
例外によっては、いくつかの問題が発生する場合があります。
"localhost" ではなく、クライアント エンドポイント アドレスをホスト名に変更することが必要になる場合があります。
アプリケーションへのポートを開く必要がある場合があります。 詳細については、SDK サンプルの ファイアウォールの手順 を参照してください。
その他の考えられる問題については、 サンプル トピック「Windows Communication Foundation サンプルの実行」を参照してください。
クライアントが Windows 資格情報を使用していて、例外が SecurityNegotiationExceptionである場合は、次のように Kerberos を構成します。
クライアントの App.config ファイル内のエンドポイント要素に ID 資格情報を追加します。
<endpoint address="http://MyServer:8000/MyService/" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServiceExample" contract="IServiceExample" behaviorConfiguration="ClientCredBehavior" name="WSHttpBinding_IServiceExample"> <identity> <userPrincipalName value="name@corp.contoso.com"/> </identity> </endpoint>
System アカウントまたは NetworkService アカウントでセルフホステッド サービスを実行します。 このコマンドを実行して、システム アカウントの下にコマンド ウィンドウを作成できます。
at 12:36 /interactive "cmd.exe"
インターネット インフォメーション サービス (IIS) でサービスをホストします。既定では、サービス プリンシパル名 (SPN) アカウントが使用されます。
SetSPN を使用して、新しい SPN をドメインに登録します。 これを行うには、ドメイン管理者である必要があります。
Kerberos プロトコルの詳細については、「 WCF で使用されるセキュリティの概念 」を参照してください。
型が例外である FaultException<Exception> をスローすると、ジェネリック型ではなく、常にクライアントで一般的な FaultException 型を受け取ります。 どうしたんですか。
独自のカスタム エラー データ型を作成し、それをエラー コントラクトの詳細型として宣言することを強くお勧めします。 その理由は、システム提供の例外の種類を使用する場合です。
サービス指向アプリケーションの最大の長所の 1 つを削除する型の依存関係を作成します。
標準の方法でシリアル化する例外に依存することはできません。 SecurityExceptionなど、シリアル化できないものもあります。
内部実装の詳細をクライアントに公開します。 詳細については、「 コントラクトとサービスでのエラーの指定と処理」を参照してください。
ただし、アプリケーションをデバッグする場合は、 ServiceDebugBehavior クラスを使用して例外情報をシリアル化し、クライアントに返すことができます。
応答にデータが含まれている場合、一方向操作と要求応答操作はほぼ同じ速度で返されるようです。 どうしてでしょうか。
操作が 1 つの方法であることを指定することは、操作コントラクトが入力メッセージを受け取り、出力メッセージを返さないことを意味します。 WCF では、送信データがネットワークに書き込まれたか、例外がスローされたときに、すべてのクライアント呼び出しが返されます。 一方向の操作は同じように動作し、サービスが見つからない場合はスローしたり、サービスがネットワークからのデータを受け入れる準備ができていない場合はブロックしたりできます。 通常、WCF では、要求応答よりも一方向の呼び出しがクライアントにすばやく返されます。ただし、ネットワーク経由での送信データの送信が遅くなる条件では、一方向の操作と要求/応答操作が遅くなります。 詳細については、「 One-Way サービス と WCF クライアントを使用したサービスへのアクセス」を参照してください。
サービスで X.509 証明書を使用していて、System.Security.Cryptography.CryptographicException を取得します。 どうしたんですか。
これは通常、IIS ワーカー プロセスを実行するユーザー アカウントを変更した後に発生します。 たとえば、Windows XP では、Aspnet_wp.exe が実行する既定のユーザー アカウントを ASPNET からカスタム ユーザー アカウントに変更すると、このエラーが表示されることがあります。 秘密キーを使用する場合、それを使用するプロセスには、そのキーを格納しているファイルにアクセスするためのアクセス許可が必要です。
その場合は、秘密キーを含むファイルに対するプロセスのアカウントに読み取りアクセス権を付与する必要があります。 たとえば、IIS ワーカー プロセスが Bob アカウントで実行されている場合は、秘密キーを含むファイルへの読み取りアクセス権を Bob に付与する必要があります。
特定の X.509 証明書の秘密キーを含むファイルへの適切なユーザー アカウント アクセス権を付与する方法の詳細については、「 方法: X.509 証明書を WCF からアクセスできるようにする」を参照してください。
操作の最初のパラメーターを大文字から小文字に変更しました。クライアントが例外をスローするようになりました。 どうしてでしょうか。
操作シグネチャのパラメーター名の値はコントラクトの一部であり、大文字と小文字が区別されます。 ローカル パラメーター名と、クライアント アプリケーションの操作を記述するメタデータを区別する必要がある場合は、 System.ServiceModel.MessageParameterAttribute 属性を使用します。
トレース ツールの 1 つを使用していて、EndpointNotFoundException を取得します。 どうしたんですか。
システム提供の WCF トレース メカニズムではないトレース ツールを使用していて、アドレス フィルターの不一致があることを示す EndpointNotFoundException を受け取る場合は、 ClientViaBehavior クラスを使用してメッセージをトレース ユーティリティに転送し、ユーティリティでそれらのメッセージをサービス アドレスにリダイレクトする必要があります。
ClientViaBehavior クラスは、To
アドレス指定ヘッダーで示される、最終的な受信側とは別に次のネットワーク アドレスを指定するように、Via
アドレス指定ヘッダーを変更します。 ただし、これを行うときは、エンドポイント アドレスを変更しないでください。エンドポイント アドレスは、 To
値の確立に使用されます。
次のコード例は、クライアント構成ファイルの例を示しています。
<endpoint
address="http://localhost:8000/MyServer/"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IMyContract"
behaviorConfiguration="MyClient"
contract="IMyContract"
name="WSHttpBinding_IMyContract">
</endpoint>
<behaviors>
<endpointBehaviors>
<behavior name="MyClient">
<clientVia viaUri="http://localhost:8001/MyServer/"/>
</behavior>
</endpointBehaviors>
</behaviors>
ベース アドレスは何ですか? エンドポイント アドレスとどのように関連していますか?
ベース アドレスは、 ServiceHost クラスのルート アドレスです。 既定では、 ServiceMetadataBehavior クラスをサービス構成に追加すると、ホストが発行するすべてのエンドポイントの Web サービス記述言語 (WSDL) が HTTP ベース アドレスと、メタデータの動作に指定された相対アドレスに加えて "?wsdl" から取得されます。 ASP.NET と IIS に慣れている場合、ベース アドレスは仮想ディレクトリと同じです。
NetTcpBinding を使用してサービス エンドポイントと mex エンドポイントの間でポートを共有する
サービスのベース アドレスを net.tcp://MyServer:8080/MyService として指定し、次のエンドポイントを追加する場合:
<services>
<service name="Microsoft.Samples.NetTcp.CalculatorService">
<endpoint address="calcsvc" binding ="netTcpBinding" contract="Microsoft.Samples.NetTcp.ICalculator"/>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
次の構成スニペットに示すように、NetTcpBinding 設定のいずれかを変更する場合:
<bindings>
<netTcpBinding>
<binding closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="11" maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
</security>
</binding>
</netTcpBinding>
</bindings>
ハンドルされない例外: System.ServiceModel.AddressAlreadyInUseException: IP エンドポイント 0.0.0.0:9000 にリスナーが既にあります。次の構成スニペットに示すように、MEX エンドポイントの別のポートで完全修飾 URL を指定することで、このエラーを回避できます。
<services>
<service name="Microsoft.Samples.NetTcp.CalculatorService">
<endpoint address="calcsvc" binding ="netTcpBinding" contract="Microsoft.Samples.NetTcp.ICalculator"/>
<endpoint address="net.tcp://localhost:9001/servicemodelsamples/mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
WCF SOAP アプリケーションから WCF Web HTTP アプリケーションを呼び出すと、サービスは次のエラーを返します。
WCF サービスから WCF Web HTTP アプリケーション (WebHttpBindingとWebHttpBehaviorを使用するサービス) を呼び出すと、次の例外が生成される場合があります。Unhandled Exception: System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: The remote server returned an unexpected response: (405) Method Not Allowed.
WCF は受信OperationContextで送信OperationContextを上書きするため、この例外が発生します。 この問題を解決するには、WCF Web HTTP サービス操作内に OperationContextScope を作成します。 例えば次が挙げられます。
public string Echo(string input)
{
using (new OperationContextScope(this.InnerChannel))
{
return base.Channel.Echo(input);
}
}