次の構成のWCFサービスがあります。
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MetadataEnabled">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MetadataEnabled" name="MyNamespace.MyService">
<endpoint name="BasicHttp"
address=""
binding="basicHttpBinding"
contract="MyNamespace.IMyServiceContract" />
<endpoint name="MetadataHttp"
address="contract"
binding="mexHttpBinding"
contract="IMetadataExchange" />
<Host>
<baseAddresses>
<add baseAddress="http://localhost/myservice" />
</baseAddresses>
</Host>
</service>
</services>
</system.serviceModel>
WcfSvcHost.exeプロセスでサービスをホストしているときに、URLを参照すると:
サービスメタデータが利用可能な場合、HTTP 400 Bad Requestエラーが発生します。
WCFログを調べると、System.Xml.XmlException例外が次のメッセージでスローされていることがわかりました: "メッセージの本文が空のため、本文を読み取ることができません。 "
ログファイルの抜粋を以下に示します。
<Exception>
<ExceptionType>
System.ServiceModel.ProtocolException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
</ExceptionType>
<Message>There is a problem with the XML that was received from the network. See inner exception for more details.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage()
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, ItemDequeuedCallback callback)
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult result)
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result)
at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.ListenerAsyncResult.WaitCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<InnerException>
<ExceptionType>System.Xml.XmlException, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>The body of the message cannot be read because it is empty.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage()
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, ItemDequeuedCallback callback)
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult result)
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result)
at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.ListenerAsyncResult.WaitCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
</InnerException>
</Exception>
代わりにURLを参照した場合:
すべてが正常に動作し、WSDLコントラクトを取得します。この時点で、 "MetadataHttp"メタデータエンドポイントを完全に削除することもできますが、何の違いもありません。
.NET 3.5 SP1を使用しています。誰かがここで何が間違っているのか考えていますか?
何が問題か分かったと思います。
URLを参照すると:
WcfTestClientアプリケーションを使用すると、サービスメタデータを正常に取得できます。
そのため、エラーは本当に、Webブラウザーを介してURLを要求したときにのみ発生します。
HTTP Bad Requestエラーは、ブラウザがメッセージのコンテンツがHTTPヘッダーと本文にあるHTTP GETリクエストを発行するという事実から生じます空です。
これはまさにWCFmexHttpBindingが不満を言っていることです!
Webブラウザーを介してサービス契約にアクセスするには、サービス動作で明示的に有効にする必要があります。
<serviceBehaviors>
<behavior name="MetadataEnabled">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
要求するURLは次のようになります。
だから、私はこの質問を投稿するのが少し早すぎることがわかりました。ただし、とにかく記録のために保管しておきます。
一般に、これはSOAPエンベロープのサイズの問題です。MaxBufferPoolSize、MaxReceivedMessageSizeを変更して大量のコンテンツを許可するには、バインディング構成を確認してください。クライアント側とサーバー側の両方で変更する必要があることに注意してください。
別の問題はMessageEnconding(別のバインディングパラメーター)です。クライアント側とサーバー側が同じエンコーディングを使用していることを確認してください。
最後に、Reader Quotas Propertiesパラメータを確認します。
WCFサービスをVisual Studio Development Serverの実行からローカルIIS Webサーバーの使用(プロジェクトを右クリック->プロパティ)に切り替えることで、「400 Bad Request」問題を修正できました。 -> [Web]タブ-> [サーバー]の下のラジオボタン。
httpsGetEnabled
がtrue
に設定されていても、SvcUtilからHTTPS mex URLを使用するとHTTP 400の問題が発生しました。エラーメッセージは実際の問題から何マイルも離れていたため、他の誰かが同じ問題に遭遇した場合に備えて、ここに投稿します。
サーバー証明書(localhost)の発行者である自己署名CA証明書(TestRootCA)がありました。クライアントでTestRootCA CERファイルをインポートしましたが、CRL(証明書失効リスト)はインポートしませんでした。自己署名CAを使用する場合はmustもCRLをインポートするようです。そうでない場合、サーバー認証が奇妙な方法で失敗し、いずれも実際の問題を示していません。さらに悪いことに、SSLハンドシェイク中に失敗が発生し、リクエストがサービスに到達するまでbeforeであるため、WCFトレースログにエラーが表示されません。
WCFコードがエラーをスローする理由がわからない場合は、MS Service Trace Viewerを強くお勧めします。このような通信とトランスポートの問題を特定するのに非常に役立ちます。詳細については、この C#コーナー の記事を参照してください。