2014-03-07 52 views
2

我开发了一些复杂的WCF服务方法。我想使用Streaming传输模式,并且因为我有多个参数,所以我定义了一个带有主体和标题的MessageContract。WCF,流式传输,消息合同错误:反序列化请求消息正文中的错误

[MessageContract] 
public class ReportAudioMessage 
{ 
    [MessageHeader] 
    public int ReportId; 

    [MessageHeader] 
    public string FileName; 

    [MessageHeader] 
    public int FileLengthInBytes; 

    [MessageHeader] 
    public int LengthInSeconds; 

    [MessageBodyMember] 
    public Stream ReportAudio; 
} 

请注意,根据我在MSDN上阅读的指南,流是唯一的身体成员。

的方法被定义为这样:

[OperationContract] 
    void SaveReportAudio(ReportAudioMessage reportToSave); 

当我尝试调用的方法(使用反射),我得到一个错误:

Error in deserializing body of request message for operation 'SaveReportAudio'. OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'SaveReportAudio' and namespace ' http://tempuri.org/ '. Found node type 'Element' with name 'ReportAudioMessage' and namespace ' http://tempuri.org/ '

SaveReportAudio是服务方法的名称我在打电话。 ReportAudioMessage是定义的MessageContract的名称。很显然,我的SOAP消息是越来越抬高了,但我不知道怎么... :(

以下是服务模型的节点,该服务的Web配置的:

<system.serviceModel> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="false" /> 
    <bindings> 
     <netTcpBinding> 
      <binding 
      name="VRManagerTcpBinding" 
      closeTimeout="00:01:00" 
      openTimeout="00:01:00" 
      sendTimeout="00:01:00" 
      receiveTimeout="00:01:00" 
      transferMode="Streamed"> 
       <reliableSession enabled="false"/> 
       <security mode="None" /> 
      </binding> 
     </netTcpBinding> 
    </bindings> 
    <services> 
     <service name="Radia.VoiceRecognition.Services.VRManager" behaviorConfiguration="VRManagerTcpBehavior"> 
      <host> 
       <baseAddresses> 
        <add baseAddress="net.tcp://localhost:8011/VRManager"/> 
       </baseAddresses> 
      </host> 
      <endpoint 
      address="VRManager.svc" 
      binding="netTcpBinding" 
      bindingConfiguration="VRManagerTcpBinding" 
      contract="Radia.VoiceRecognition.Services.IVRManager" /> 
      <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="VRManagerTcpBehavior"> 
     <serviceMetadata httpGetEnabled="false" /> 
     <serviceDebug includeExceptionDetailInFaults="true" /> 
     </behavior> 
     </serviceBehaviors> 
     </behaviors> 
</system.serviceModel> 

这里是客户App.Config中的服务模式节点:

<system.serviceModel> 
<bindings> 
    <netTcpBinding> 
    <binding name="NetTcpBinding_IVRManager" closeTimeout="00:01:00" 
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
     transactionFlow="false" transferMode="Streamed" 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="None"> 
     <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> 
     <message clientCredentialType="Windows" /> 
     </security> 
    </binding> 
    </netTcpBinding> 
</bindings> 
<client> 
    <endpoint address="net.tcp://xxxxxxxxxxx:8012/VRManager.svc/VRManager.svc" 
    binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IVRManager" 
    contract="VRManager.IVRManager" name="NetTcpBinding_IVRManager" /> 
</client> 

+0

你找到答案了吗? SO上的其他人遇到同样的问题。 –

+0

供参考:请参阅http://stackoverflow.com/questions/19423004/error-in-deserializing-body-of-request-message-for-operation-abc –

+0

嗨安东尼。我确实解决了这个问题,我会在这里发布。虽然,它真的感觉像一个黑客 - 但它的工作... – essedbl

回答

1

我能得到这个工作,虽然我不是很满意的解决方案,我觉得这是一个黑客,部分原因是因为一世不完全理解它。

思考错误后,我决定启用WCF跟踪,看看我能找到什么。我看到了Xml消息并注意到该元素的名称实际上是“ReportAudioMessage”。因此,我决定修改邮件合同,并设置WrapperName:

[MessageContract(IsWrapped = true, WrapperName = "SaveReportAudio")] 
public class ReportAudioMessage 
{ 
    [MessageBodyMember] 
    public Stream Session; 
} 

请注意“WrapperName”属性。现在,这是我的WCF服务上的方法的名称。现在起作用了。然而,这是令人沮丧,因为我现在这个工作在两种方法 - 保存方法和get方法:

[OperationContract] 
void SaveReportAudio(ReportAudioMessage message); 

[OperationContract] 
ReportAudioMessage GetReportAudio(GetReportAudioRequestMessage request); 

总之,这是为我工作,所以我只是用我下去。我将不胜感激任何进一步的意见或建议。谢谢,