13

次の構成の 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://localhost/myservice/contract

サービス メタデータが利用可能な場合、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 を参照すると、次のようになります。

http://localhost/myservice?wsdl

すべてが正常に機能し、WSDL コントラクトを取得します。この時点で、「MetadataHttp」メタデータ エンドポイントを完全に削除することもできますが、違いはありません。

.NET 3.5 SP1 を使用しています。ここで何が間違っているのか、誰かが考えていますか?

4

5 に答える 5

13

問題が何であるかがわかったと思います。

URL を参照すると、次のようになります。

http://localhost/myservice/contract

WcfTestClientアプリケーションを使用すると、サービス メタデータを正常に取得できます。
したがって、エラーは実際には、Web ブラウザーを介して URL を要求した場合にのみ発生します。

HTTP Bad Requestエラーは、メッセージの内容が HTTP ヘッダーにあり、本文が空である HTTP GET 要求をブラウザーが発行するという事実から発生します。
これはまさに WCF のmexHttpBindingが訴えていることです!

Web ブラウザ経由でサービス コントラクトにアクセスするには、サービス ビヘイビアで明示的に有効にする必要があります。

<serviceBehaviors>
    <behavior name="MetadataEnabled">
        <serviceMetadata httpGetEnabled="true" />
    </behavior>
</serviceBehaviors>

リクエストする URL は次のようになります。

http://localhost/myservice?wsdl

したがって、この質問を投稿するのは少し早すぎたことがわかりました。とはいえ、記録として残しておきます。

于 2008-11-27T12:04:06.830 に答える
4

一般に、これは SOAP エンベロープのサイズに問題があります。MaxBufferPoolSize、MaxReceivedMessageSize を変更して巨大なコンテンツを許可するには、バインディング構成を確認してください。クライアント側とサーバー側の両方で変更する必要があることに注意してください。

もう 1 つの問題は MessageEnconding (別のバインディング パラメーター) です。クライアント側とサーバー側が同じエンコーディングを使用していることを確認してください。

最後に、Reader Quotas Properties パラメーターを確認します。

于 2010-11-10T19:42:47.947 に答える
3

WCF サービスを Visual Studio Development Server の実行からローカル IIS Web サーバーの使用に切り替えることで、「400 Bad Request」の問題を修正できました (プロジェクトを右クリック --> プロパティ --> Web タブ --> ラジオ「サーバー」の下のボタン)。これを理解するのに2日かかったので、これが誰かの助けになることを願っています.

于 2010-03-18T13:24:43.410 に答える
2

httpsGetEnabledに設定されていても、SvcUtil から HTTPS mex URL を使用すると、HTTP 400 の問題が発生しましたtrue。エラー メッセージは実際の問題とはかけ離れていたので、他の誰かが同じ問題に遭遇した場合に備えてここに投稿します。

サーバー証明書 (localhost) の発行者である自己署名 CA 証明書 (TestRootCA) がありました。クライアントで TestRootCA CER ファイルをインポートしましたが、CRL (証明書失効リスト) をインポートしませんでした。自己署名 CA を使用する場合は、CRL もインポートする必要があるようです。そうしないと、サーバー認証が奇妙な方法で失敗し、実際の問題を指摘するものはありません。さらに悪いことに、リクエストがサービスに到達する前に、SSL ハンドシェイク中にエラーが発生するため、WCF トレース ログにエラーは表示されません。

于 2014-03-26T17:36:18.830 に答える