我正在我的服务上测试故障和异常处理,并且看到奇怪的结果。
我有一个配置了两个端点的服务合同。一个是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" />
[编辑]
绑定配置:
basicHttpBinding的
<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 body中的正确SOAP错误,但基本不是。当本地运行而不是从真正的服务器运行时,使用basicHttpBinding返回Soap故障。
答案 0 :(得分:2)
我的basicHttp端点出现了同样的错误。我想把我的web.config的编码从'Ansi as utf8'改为'utf8'
答案 1 :(得分:1)
我在问题中找到了问题所在。这是一个简单的配置更改(需要几个小时才能找到)。在我的绑定中,我改变了
transferMode="Streamed"
到
transferMode="Buffered"
答案 2 :(得分:0)
我一直在寻找两天,试图找到一个解决方案并解释为什么我的自定义SOAP错误的WCF服务拒绝工作,IIS反而吐出http 500错误,具有相同的客户端异常:< em>“响应消息的内容类型text / html与绑定的内容类型不匹配......”。
最糟糕的是它在IIS Express上本地工作或使用ServiceHost
实例!
您的回答极大地帮助我诊断并解决了问题,谢谢。
以下是我感兴趣的人的解决方案和解释。
通常,在使用错误时,对客户端的响应是包含错误详细信息的SOAP xml消息(使用text / 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>
就是这样!