2014-03-07 4 views
2

복잡한 WCF 서비스 메서드를 조금 개발했습니다. 스트리밍 전송 모드를 사용하고 싶습니다. 둘 이상의 매개 변수가 있기 때문에 본문과 머리글이있는 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에서 읽는 지침에 따라 본문의 유일한 구성원입니다.

방법은 다음과 같이 정의된다

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이 서비스 방법의 이름입니다

[OperationContract] 
    void SaveReportAudio(ReportAudioMessage reportToSave); 

나는 방법 (반사를 사용)를 호출을 시도, 나는 오류가 발생 나는 부르고있다. ReportAudioMessage는 정의 된 MessageContract의 이름입니다. 분명히, 내 SOAP 메시지가 밀어 올려지고,하지만 난 :(... 어떻게 다음

을 모르는 서비스 모델 노드는 서비스의 웹 설정의이다 : 여기

<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

답변을 찾았습니까? 그래서 다른 사람이 같은 문제를 겪고 있습니다. –

+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 서비스의 메서드 이름입니다. 이제 작동합니다.

[OperationContract] 
void SaveReportAudio(ReportAudioMessage message); 

[OperationContract] 
ReportAudioMessage GetReportAudio(GetReportAudioRequestMessage request); 

어쨌든, 나를 위해 노력하고, 그래서 난 그냥 함께 갈거야 : 세이브 방법 및 get 메소드를 -이 두 가지 방법에 지금 작동하기 때문에, 그것은 나를 실망한다. 더 이상의 의견이나 조언을 부탁드립니다. 감사합니다.