C# WCF合约不匹配问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1264431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WCF contract mismatch problem
提问by
I have a client console app talking to a WCF service and I get the following error: "The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error."
我有一个客户端控制台应用程序与 WCF 服务通信,但出现以下错误:“服务器没有提供有意义的答复;这可能是由于合同不匹配、会话过早关闭或内部服务器错误造成的。”
I think it's because of a contract mismatch but i can't figure out why. The service runs just fine by itself and the 2 parts were working together until i added the impersonation code.
我认为这是因为合同不匹配,但我不知道为什么。该服务本身运行得很好,这两个部分一直在协同工作,直到我添加了模拟代码。
Can anyone see what is wrong?
任何人都可以看到有什么问题吗?
Here is the client, all done in code:
这是客户端,全部在代码中完成:
NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
EndpointAddress endPoint = new EndpointAddress(new Uri("net.tcp://serverName:9990/TestService1"));
ChannelFactory<IService1> channel = new ChannelFactory<IService1>(binding, endPoint);
channel.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
IService1 service = channel.CreateChannel();
And here is the config file of the WCF service:
这是 WCF 服务的配置文件:
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="MyBinding">
<security mode="Message">
<transport clientCredentialType="Windows"/>
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="WCFTest.ConsoleHost2.Service1Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceAuthorization impersonateCallerForAllOperations="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="WCFTest.ConsoleHost2.Service1Behavior"
name="WCFTest.ConsoleHost2.Service1">
<endpoint address="" binding="wsHttpBinding" contract="WCFTest.ConsoleHost2.IService1">
<identity>
<dns value="" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint binding="netTcpBinding" bindingConfiguration="MyBinding"
contract="WCFTest.ConsoleHost2.IService1" />
<host>
<baseAddresses>
<add baseAddress="http://serverName:9999/TestService1/" />
<add baseAddress="net.tcp://serverName:9990/TestService1/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
回答by
Ok, i've just changed the client so it uses a config file instead of code and I get the same error!
好的,我刚刚更改了客户端,因此它使用配置文件而不是代码,但我遇到了同样的错误!
Code:
代码:
ServiceReference1.Service1Client client = new WCFTest.ConsoleClient.ServiceReference1.Service1Client("NetTcpBinding_IService1");
client.PrintMessage("Hello!");
Here is the config file of the client, freshly generated from the Service ... which makes my think that it mightn't be a contract mismatch error
这是客户端的配置文件,从服务中新鲜生成......这让我认为它可能不是合同不匹配错误
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IService1" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://servername:9999/TestService1/" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
name="WSHttpBinding_IService1">
<identity>
<dns value="
 " />
</identity>
</endpoint>
<endpoint address="net.tcp://serverName:9990/TestService1/" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IService1" contract="ServiceReference1.IService1"
name="NetTcpBinding_IService1">
<identity>
<userPrincipalName value="MyUserPrincipalName " />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
回答by Simon_Weaver
Other possible causes:
其他可能的原因:
- Trying to serialize an object without a default constructor.
- Trying to serialize some other kind of non serializable object (such as an Exception). To prevent the item from being serialized apply
[IgnoreDataMember]
attribute to the field or property. - Check your enum fields to make sure they are set to a valid value (or are nullable). You may need to add a 0 value to the enum in some cases. (not sure about fine details of this point).
- 尝试在没有默认构造函数的情况下序列化对象。
- 尝试序列化某种其他类型的不可序列化对象(例如异常)。为了防止项目被序列化,将
[IgnoreDataMember]
属性应用到字段或属性。 - 检查您的枚举字段以确保它们设置为有效值(或可为空)。在某些情况下,您可能需要向枚举添加 0 值。(不确定这一点的细节)。
What to test:
测试内容:
Configure WCF tracingfor at least critical errors or exceptions. Be careful to watch filesize if you enable any further traces. This will give some very useful information in many cases.
Just add this under
<configuration>
in yourweb.config
ON THE SERVER. Create thelog
directory if it doesn't exist.
至少为严重错误或异常配置 WCF 跟踪。如果您启用任何进一步的跟踪,请小心观察文件大小。在许多情况下,这将提供一些非常有用的信息。
只需将其添加
<configuration>
到您的web.config
ON THE SERVER 下即可。log
如果目录不存在,则创建该目录。
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Error, Critical"
propagateActivity="true">
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "c:\log\WCF_Errors.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
- Make sure the .svc file will actually come up in a browser without error. This will give you some 'first chance' help. For instance if you have a non serializable object you'll get this message below. Note that it clearly tells you what can't be serialized. Make sure you have 'mex' endpoint enabled and bring up the .svc file in your browser.
- 确保 .svc 文件将在浏览器中实际出现而不会出错。这会给你一些“第一次机会”的帮助。例如,如果您有一个不可序列化的对象,您将在下面收到此消息。请注意,它清楚地告诉您不能序列化的内容。确保您启用了“mex”端点并在浏览器中调出 .svc 文件。
An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior contract: http://tempuri.org/:IOrderPipelineService----> System.Runtime.Serialization.InvalidDataContractException: Type 'RR.MVCServices.PipelineStepResponse' cannot be serialized.Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.
可能由 IncludeExceptionDetailInFaults=true 创建的 ExceptionDetail,其值为: System.InvalidOperationException:在调用 WSDL 导出扩展时抛出异常:System.ServiceModel.Description.DataContractSerializerOperationBehavior 合同:http://tempuri.org/: IOrderPipelineService----> System.Runtime.Serialization.InvalidDataContractException: 类型 'RR.MVCServices.PipelineStepResponse' 无法序列化。考虑使用 DataContractAttribute 特性标记它,并使用 DataMemberAttribute 特性标记要序列化的所有成员。
回答by Paul D
For me, this error message was thrown because my the web.config Service Behavior by default has a low message limit, so when the WCF returned say 200000 bytes and my limit was 64000 bytes the response was truncated and thus you get the "... not meaningful reply". It's meaningful, it's just been truncated and can't be parsed.
对我来说,抛出此错误消息是因为我的 web.config 服务行为默认具有较低的消息限制,因此当 WCF 返回 200000 字节而我的限制为 64000 字节时,响应被截断,因此您得到“.. . 没有意义的回复”。是有意义的,只是被截断了,无法解析。
I'll paste my web.config change that fixed the issue:
我将粘贴解决问题的 web.config 更改:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="YourNameSpace.DataServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<serviceTimeouts transactionTimeout="05:05:00" />
<serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500"
maxConcurrentInstances="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
The maxItemsInObjectGraph value is the most important!
I hope this helps anyone.
maxItemsInObjectGraph 值是最重要的!
我希望这可以帮助任何人。
回答by sivaprakash
If you have two methods with same name and parameters in your WCF it will throw this error
如果您的 WCF 中有两个具有相同名称和参数的方法,则会引发此错误
回答by Varun Bedi
I was having a similar issue. After spending a mind bending 2 hours on this and trying to find an answer online, I decided to follow the approach to seralize and deserialize the return value/object on the server side using the System.Runtime.Serialization.DataContractSerializer and finally found that I had missed to add EnumMember attribute on one of the Enums.
我遇到了类似的问题。在花了 2 个小时的时间思考并尝试在网上找到答案后,我决定按照使用 System.Runtime.Serialization.DataContractSerializer 在服务器端对返回值/对象进行序列化和反序列化的方法,最后发现我错过了在枚举之一上添加 EnumMember 属性。
You may be facing a similar issue.
您可能正面临类似的问题。
Here is the code snippet that helped me resolve the issue:
这是帮助我解决问题的代码片段:
var dataContractSerializer = new System.Runtime.Serialization.DataContractSerializer(typeof(MyObject));
byte[] serializedBytes;
using (System.IO.MemoryStream mem1 = new System.IO.MemoryStream())
{
dataContractSerializer.WriteObject(mem1, results);
serializedBytes = mem1.ToArray();
}
MyObject deserializedResult;
using (System.IO.MemoryStream mem2 = new System.IO.MemoryStream(serializedBytes))
{
deserializedResult = (MyObject)dataContractSerializer.ReadObject(mem2);
}