【问题标题】:WCF basicHttp endpoint returns server 500 but wsHttp endpoint doesn'tWCF basicHttp 端点返回服务器 500,但 wsHttp 端点没有
【发布时间】:2026-01-28 08:20:02
【问题描述】:

我正在测试我的服务的故障和异常处理,并看到奇怪的结果。

我有一个配置了两个端点的服务合同。一个是basicHttpBinding,另一个是wsHttpBinding。在我的机器上本地我有一个测试应用程序客户端和服务器正在运行。我可以成功调用这两个 Web 服务绑定并获得我正在寻找的异常,这正是我正在寻找的。但是当我将代码推送到开发服务器时,我只能成功调用 wsHttpBinding 端点。基本端点返回一条奇怪的消息。例外是“远程服务器返回错误:(500) 内部服务器错误。”

异常消息是:

"响应消息的内容类型 text/html 与绑定的内容类型不匹配 (text/xml; charset=utf-8)。如果使用自定义编码器,请确保 IsContentTypeSupported 方法正确实现。响应的前1024字节是:在此处插入一堆废话html”

这是配置错误吗? IIS 错误?防火墙问题?我已经在服务器上运行了 WCF 日志记录和跟踪。我的代码被击中得很好,它抛出了一个错误异常。 basicHttpBinding 上的消息头是空的,但我不确定这是否有问题。我也检查了 IIS 日志。它显示了 500 个错误,仅此而已。还有什么需要检查的吗?

我的端点:

<endpoint 
 address="" 
 binding="wsHttpBinding" 
 bindingConfiguration="WSHttpBinding_IEOIEligible_NONSSL"
 name="IEOIEligible_Svc_endpoint_NONSSL" 
 contract="Engine.IEOIEligible">
</endpoint>

<endpoint 
address="mex" 
binding="mexHttpBinding" 
name="Mex_Svc_endpoint"
contract="IMetadataExchange" />

<endpoint 
    address="/basic" 
    binding="basicHttpBinding" 
    bindingConfiguration="BasicHttpBinding_IEOIEligible"
    name="basicEOIEndpoint" 
    contract="Engine.IEOIEligible" />

[编辑]

绑定配置:

基本的HttpBinding

<binding name="BasicHttpBinding_IEOIEligible" closeTimeout="00:01:00"
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
      allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
      maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
      messageEncoding="Text" textEncoding="utf-8" transferMode="Streamed"
      useDefaultWebProxy="true">
      <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="16384"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="None">
        <transport clientCredentialType="Certificate" proxyCredentialType="None"
          realm="" />
        <message clientCredentialType="Certificate" algorithmSuite="Default" />
      </security>
    </binding>

wsHttpBinding

<binding name="WSHttpBinding_IEOIEligible_NONSSL" closeTimeout="00:10:00"
      openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
                maxBufferPoolSize="524288" maxReceivedMessageSize="524288" messageEncoding="Text"
      textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
      <readerQuotas maxDepth="32" maxStringContentLength="819200" maxArrayLength="16384"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00"
        enabled="false" />
    </binding>

来自 WCF 跟踪文件:

调用成功(wsHttp):

<ExtendedData     xmlns="http://schemas.microsoft.com/2006/08/ServiceModel/MessageTraceRecord">
 <MessageProperties>
  <Encoder>application/soap+xml; charset=utf-8</Encoder>
  <AllowOutputBatching>False</AllowOutputBatching>
 </MessageProperties>
 <MessageHeaders>
  <Action d4p1:mustUnderstand="1" xmlns:d4p1="http://www.w3.org/2003/05/soap-envelope" xmlns="http://www.w3.org/2005/08/addressing">http://tempuri.org/IEOIEligible/VerifyEOIRequiredEOIEligibilityFaultFault</Action>
 <RelatesTo xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:5863c107-b721-4b4c-88b8-0d03c22175d1</RelatesTo>
 <ActivityId CorrelationId="a498440c-2e5a-4298-9bc5-ade08d51933c" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">00000000-0000-0000-0000-000000000000</ActivityId>
 </MessageHeaders>
</ExtendedData>

服务器 500 (basicHttp)

<ExtendedData xmlns="http://schemas.microsoft.com/2006/08/ServiceModel/MessageTraceRecord">
 <MessageProperties>
  <Encoder>text/xml; charset=utf-8</Encoder>
  <AllowOutputBatching>False</AllowOutputBatching>
 </MessageProperties>
 <MessageHeaders></MessageHeaders>
</ExtendedData>

[编辑]

我能够通过 Microsoft WCF 测试客户端使用 basicHttpBinding 从服务中获得响应,但这只是当我没有在服务器上抛出 FaultException 时,这意味着服务返回了愉快的路径。这部分我不关心,谢天谢地。

我正在对客户端异常处理进行单元测试,并且服务器在基本而不是 wsHttpBinding 上返回 500。 wsHttpBinding 返回嵌入在肥皂体内的正确 SOAP 错误,但基本不是。 Soap 错误在本地运行时返回 basicHttpBinding,而不是从真正的服务器运行。

【问题讨论】:

  • 能否为问题添加绑定配置?
  • @dharnitski 我添加了绑定配置。谢谢!
  • 你能用 Fiddler 之类的东西来查看调用 BasicHttpBinding 时返回的 HTML 页面是什么吗?此外,不要使用消息日志,而是尝试使用 WCF tracing(诊断),它应该包含有关错误的更多信息。

标签: wcf soap


【解决方案1】:

我的 basicHttp 端点也出现了同样的错误。我想将我的 web.config 的编码从“Ansi as utf8”更改为“utf8”

【讨论】:

    【解决方案2】:

    我发现了我的问题的问题。这是一个简单的配置更改(需要几个小时才能找到)。在我的绑定中我改变了

    transferMode="Streamed"
    

    transferMode="Buffered"
    

    【讨论】:

      【解决方案3】:

      我已经四处寻找两天了,试图找到一个解决方案并解释为什么我的带有自定义 SOAP 错误的 WCF 服务拒绝工作,IIS 吐出 http 500 错误,但客户端异常相同:“响应消息的内容类型text/html与绑定的内容类型不匹配...”.

      最糟糕的是它在 IIS Express 上本地运行或使用 ServiceHost 实例!

      您的回答对我诊断和解决问题有很大帮助,谢谢。

      这是我为感兴趣的人提供的解决方案和解释。


      通常,当使用故障时,对客户端的响应是包含错误详细信息的 SOAP xml 消息(当使用文本/xml 消息编码器时)。

      使用Fiddler,我能够拦截并查看以缓冲模式和流模式发送回客户端的响应。

      这是缓冲模式下的响应消息:

      <?xml version="1.0" encoding="UTF-8"?>
      <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
         <s:Header>
            <a:Action s:mustUnderstand="1">http://tempuri.org/ISIAdministration/MyServiceBusinessFaultFault</a:Action>
            <a:RelatesTo>urn:uuid:a6a89101-7d95-4e7b-9871-c43792559f16</a:RelatesTo>
         </s:Header>
         <s:Body>
            <s:Fault>
               <s:Code>
                  <s:Value>s:Sender</s:Value>
               </s:Code>
               <s:Reason>
                  <s:Text xml:lang="fr-FR">Le créateur de cette erreur n'a pas spécifié de raison.</s:Text>
               </s:Reason>
               <s:Detail>
                  <BusinessFault xmlns="http://schemas.datacontract.org/2004/07/GI.Framework.Error" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                     <MyCode>test</MyCode>
                     <MyMessage>test</MyMessage>
                  </BusinessFault>
               </s:Detail>
            </s:Fault>
         </s:Body>
      </s:Envelope>
      

      这是流模式下的响应消息:

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
      <title>500 - Erreur interne au serveur.</title>
      <style type="text/css">
      <!--
      body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
      fieldset{padding:0 15px 10px 15px;} 
      h1{font-size:2.4em;margin:0;color:#FFF;}
      h2{font-size:1.7em;margin:0;color:#CC0000;} 
      h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} 
      #header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
      background-color:#555555;}
      #content{margin:0 0 0 2%;position:relative;}
      .content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
      -->
      </style>
      </head>
      <body>
      <div id="header"><h1>Erreur de serveur</h1></div>
      <div id="content">
       <div class="content-container"><fieldset>
        <h2>500 - Erreur interne au serveur.</h2>
        <h3>La ressource que vous recherchez présente un problème, elle ne peut donc pas être affichée.</h3>
       </fieldset></div>
      </div>
      </body>
      </html>
      <?xml version="1.0" encoding="UTF-8"?>
      <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
         <s:Header>
            <a:Action s:mustUnderstand="1">http://tempuri.org/ISIAdministration/MyServiceBusinessFaultFault</a:Action>
            <a:RelatesTo>urn:uuid:a6a89101-7d95-4e7b-9871-c43792559f16</a:RelatesTo>
         </s:Header>
         <s:Body>
            <s:Fault>
               <s:Code>
                  <s:Value>s:Sender</s:Value>
               </s:Code>
               <s:Reason>
                  <s:Text xml:lang="fr-FR">Le créateur de cette erreur n'a pas spécifié de raison.</s:Text>
               </s:Reason>
               <s:Detail>
                  <BusinessFault xmlns="http://schemas.datacontract.org/2004/07/GI.Framework.Error" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                     <MyCode>test</MyCode>
                     <MyMessage>test</MyMessage>
                  </BusinessFault>
               </s:Detail>
            </s:Fault>
         </s:Body>
      </s:Envelope>
      

      注意到有什么奇怪的吗?

      由于我忽略的一个原因,似乎 IIS 对缓冲或流式响应的错误处理方式不同,它实际上在预期的 xml 消息之前插入了自定义 500 错误页面的内容!!!强>

      IIS 还将响应的 Content-Type 更改为 text/html,这解释了异常消息。

      这就是为什么在您的情况下从流式消息切换到缓冲消息可以解决问题,但在我的情况下,此解决方案是不可接受的,因为我需要传输数百兆字节的数据。


      一旦我接受了这很可能是一个 IIS 错误而不是我的配置问题的事实,找到解决方案就很容易了:

      TL;DR:

      问题来自 IIS 自定义错误页面,因此您只需为您的服务禁用它们。这可以从 IIS 管理面板完成,也可以通过向 web.config 文件添加一个简单的配置指令来完成,指示 IIS 让现有的错误消息通过而不改变它们:

      <system.webServer>
          <httpErrors existingResponse="PassThrough" />
      </system.webServer>
      

      就是这样!

      【讨论】: