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 GET 请求,其中消息的内容在 HTTP 标头中,并且正文为空。
这正是 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 以允许大量内容。请记住,您必须在客户端和服务器端都进行更改。

另一个问题是 MessageEnconding(另一个绑定参数),确保客户端和服务器端使用相同的编码。

最后,检查 Reader Quotas Properties 参数。

于 2010-11-10T19:42:47.947 回答
3

我能够通过将我的 WCF 服务从运行 Visual Studio 开发服务器切换到使用本地 IIS Web 服务器来修复“400 错误请求”问题(右键单击项目 --> 属性 --> web 选项卡 --> 无线电“服务器”下的按钮)。我希望这对那里的人有所帮助,因为我花了两天时间才弄清楚这一点。

于 2010-03-18T13:24:43.410 回答
2

如果你不确定你的 WCF 代码为什么会抛出错误,那么我强烈推荐 MS Service Trace Viewer。这对于识别此类通信和传输问题非常有帮助。查看这篇C# Corner文章了解更多详细信息。

于 2011-03-23T02:43:47.353 回答
2

从 SvcUtil 使用 HTTPS mex URL 时,我遇到了 HTTP 400 问题,尽管httpsGetEnabled设置为true. 错误消息与真正的问题相去甚远,所以我在这里发布,以防其他人偶然发现同样的问题。

我有一个自签名 CA 证书 (TestRootCA),它是服务器证书 (localhost) 的颁发者。在客户端上,我导入了 TestRootCA CER 文件,但没有导入 CRL(证书吊销列表)。似乎当您使用自签名 CA 时,您还必须导入 CRL,否则服务器身份验证会以奇怪的方式失败,这些都没有指向真正的问题。更糟糕的是,失败发生在 SSL 握手期间,甚至请求到达您的服务之前,因此您不会在 WCF 跟踪日志中看到任何错误。

于 2014-03-26T17:36:18.830 回答