请求 WCF 服务合同时出现 HTTP 错误请求错误 [英] HTTP Bad Request error when requesting a WCF service contract

查看:17
本文介绍了请求 WCF 服务合同时出现 HTTP 错误请求错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 WCF 服务,配置如下:

I have a WCF service with the following configuration:

<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:

When hosting the service in the WcfSvcHost.exe process, if I browse to the URL:

http://localhost/myservice/contract

在提供服务元数据的地方,我收到 HTTP 400 错误请求 错误.

通过检查 WCF 日志,我发现 System.Xml.XmlException 异常与消息一起抛出:消息正文无法读取,因为它是空的."
这是日志文件的摘录:

where the service metadata is available I get an HTTP 400 Bad Request error.

By inspecting the WCF logs I found out that an System.Xml.XmlException exception is being thrown with the message: "The body of the message cannot be read because it is empty."
Here is an extract of the log file:

<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:

If I instead browse to the URL:

http://localhost/myservice?wsdl

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

everything works just fine and I get the WSDL contract. At this point, I can also remove the "MetadataHttp" metadata endpoint completely, and it wouldn't make any difference.

我使用的是 .NET 3.5 SP1.有没有人知道这里可能出了什么问题?

I'm using .NET 3.5 SP1. Does anyone have an idea of what could be wrong here?

推荐答案

我想我找到了问题所在.

I think I found out what the problem is.

如果我浏览到 URL:

If I browse to the URL:

http://localhost/myservice/contract

使用 WcfTestClient 应用程序,我可以成功检索服务元数据.
所以错误只发生在我通过网络浏览器请求 URL 时.

with the WcfTestClient application I can successfully retrieve the service metadata.
So the error really only occurs when I request the URL through a web browser.

HTTP 错误请求 错误来自以下事实:浏览器发出 HTTP GET 请求,其中消息的内容位于 HTTP 标头中,而正文为空.
这正是 WCF mexHttpBinding 所抱怨的!

为了通过 Web 浏览器访问服务合同,您必须在服务行为中显式启用它:

The HTTP Bad Request error comes from the fact that the browser issues an HTTP GET request where the contents of the message are in the HTTP headers, and the body is empty.
This is exactly what the WCF mexHttpBinding is complaining about!

In order to get to the service contract via a web browser you will have to explicitly enable it in the service behavior:

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

请求的 URL 变为:

The URL to request becomes then:

http://localhost/myservice?wsdl

所以,事实证明我发布这个问题有点太快了.不过,我还是会保留它作为记录.

So, it turns out I was a little too quick in posting this question. However, I'll keep it anyway just for the record.

这篇关于请求 WCF 服务合同时出现 HTTP 错误请求错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆