请求WCF服务合同时出现HTTP错误请求错误

时间:2008-11-27 11:49:49

标签: wcf http exception wsdl

我有一个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 进程中托管服务时,如果我浏览到该网址:

  

http://localhost/myservice/contract

服务元数据可用时,我收到 HTTP 400错误请求错误。

通过检查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>

如果我改为浏览网址:

  

http://localhost/myservice?wsdl

一切正常,我得到了WSDL合同。此时,我还可以完全删除“MetadataHttp”元数据端点,它不会有任何区别。

我正在使用.NET 3.5 SP1。有没有人知道这里可能出现什么问题?

5 个答案:

答案 0 :(得分:12)

我想我发现了问题所在。

如果我浏览到URL:

  

http://localhost/myservice/contract

使用 WcfTestClient 应用程序,我可以成功检索服务元数据 因此,只有当我通过Web浏览器请求URL时才会出现错误。

HTTP错误请求错误来自以下事实:浏览器发出HTTP GET请求,其中邮件的内容位于HTTP标头中,并且正文为空。
正是WCF mexHttpBinding 正在抱怨的内容!

要通过Web浏览器获取服务合同,您必须在服务行为中明确启用它:

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

然后请求的URL成为:

  

http://localhost/myservice?wsdl

所以,事实证明我发布这个问题有点太快了。但是,我会保留它,只是为了记录。

答案 1 :(得分:4)

通常,这是SOAP信封大小的问题。检查绑定配置以更改MaxBufferPoolSize,MaxReceivedMessageSize以允许大量内容。请记住,您必须在客户端和服务器端进行更改。

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

最后,检查Reader Quotas Properties参数。

答案 2 :(得分:3)

通过将我的WCF服务从运行Visual Studio Development Server转移到使用本地IIS Web服务器(右键单击项目 - &gt;属性 - &gt; web),我能够修复“400 Bad Request”问题选项卡 - &gt;“服务器”下的单选按钮)。我希望这可以帮助那里的人,因为我花了两天时间才想出这个。

答案 3 :(得分:2)

如果您不确定为什么您的WCF代码会抛出错误,那么我强烈推荐使用MS Service Trace Viewer。它非常有助于识别这样的通信和传输问题。有关详细信息,请查看此C# Corner文章。

答案 4 :(得分:2)

从SvcUtil使用HTTPS mex网址时遇到HTTP 400问题,尽管httpsGetEnabled设置为true。错误消息距离真正的问题几英里远,所以我发布在这里以防万一其他人偶然发现同样的问题。

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