none
WCF Message Inspector -- This message cannot support the operation because it has been written RRS feed

  • Question

  • Hi,

    implemented a simple message inspector in a WCF WS hosted in IIS. but getting this error 'This message cannot support the operation because it has been written'.

    My implementation 

    public class MessageInspector : IDispatchMessageInspector
        {
            public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
            {
                if (!request.IsFault)
                {
                    MessageBuffer buffer = request.CreateBufferedCopy(10000000);
                    request = buffer.CreateMessage();
     
                    var message = buffer.CreateMessage();
                    using (XmlDictionaryReader reader = message.GetReaderAtBodyContents())
                    {
                        // read the message
                    }
                }
     
                return null;
            }

    Any idea what is wrong with this code? 

    thank you,

    -Abraham

    Monday, December 11, 2017 9:36 PM

All replies

  • Hi Abraham,

    Could you share us a simple project which could reproduce your issue?

    I made a test with below code, it works correctly.

    Inspector
    
    
    namespace WCFInspectorApp
    {
        public class MessageInspector : BehaviorExtensionElement, IDispatchMessageInspector, IServiceBehavior
        {
            public override Type BehaviorType
            {
                get
                {
                    return typeof(MessageInspector);
                }
            }
    
            public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
            {
                
            }
           
            public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
            {
                if (!request.IsFault)
                {
                    MessageBuffer buffer = request.CreateBufferedCopy(10000000);
                    request = buffer.CreateMessage();
                    var message = buffer.CreateMessage();
                    using (XmlDictionaryReader reader = message.GetReaderAtBodyContents())
                    {
                        // read the message
                    }
                }
    
                return null;
            }
    
            public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
            {
                foreach (ChannelDispatcher chDisp in serviceHostBase.ChannelDispatchers)
                {
                    foreach (EndpointDispatcher epDisp in chDisp.Endpoints)
                    {
                        epDisp.DispatchRuntime.MessageInspectors.Add(this);
                    }
                }
            }
    
            public void BeforeSendReply(ref Message reply, object correlationState)
            {
            }
    
            public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
            {
            }
    
            protected override object CreateBehavior()
            {
                return new MessageInspector();
            }
        }
    }
    
    //web.config
    
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
              <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
              <serviceDebug includeExceptionDetailInFaults="false"/>
              <MessageInspector />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <protocolMapping>
            <add binding="basicHttpsBinding" scheme="https"/>
        </protocolMapping>    
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
        <extensions>
          <behaviorExtensions>
            <add
              name="MessageInspector"
              type="WCFInspectorApp.MessageInspector, WCFInspectorApp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
            />
          </behaviorExtensions>
        </extensions>
      </system.serviceModel>
    

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, December 13, 2017 7:38 AM
  • Hi Tao Zhou,

    Thank you for the reply.

    In my dev environment, my WCF WS have two end points. Secured with certificates and another not secured (for dev testing). This WS is consumed by other non .net clients.

    I used SoapUI to send requests to unsecured end point, the message inspector is working fine without any exceptions. but the secured end point is throwing exception (even with a WCF client)

    the end point configuration is as

    <service name="MyService" behaviorConfiguration="certBehavior">
            <endpoint address="" binding="customBinding" bindingConfiguration="notSecure01" contract="xxxx_Ext_PortType_V1_0" behaviorConfiguration="inspectorBehavior"/>
            <endpoint address="secure" binding="customBinding" bindingConfiguration="MutualCertBinding01" contract="xxxx_Ext_PortType_V1_0" behaviorConfiguration="inspectorBehavior" />
    </service>

    <binding name="MutualCertBinding01">
              <textMessageEncoding messageVersion="Soap12" />
              <security authenticationMode="MutualCertificate" securityHeaderLayout="Lax" allowSerializedSigningTokenOnReply="true" messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
                <secureConversationBootstrap />
              </security>
              <httpsTransport maxReceivedMessageSize="10000000" />
    </binding>

    <binding name="notSecure01">
              <textMessageEncoding messageVersion="Soap12" />
              <httpsTransport maxReceivedMessageSize="10000000" />
    </binding>

    thank you,

    -Abraham

    Wednesday, December 13, 2017 1:56 PM
  • Hi Abraham,

    Could you debug your code? Which line did you get this exception?

    I suggest you try code below to recreate the message.

    //Now recreating the message
        ms = new MemoryStream();
        xmlDoc.Save(ms);
        ms.Position = 0;
        XmlReader reader = XmlReader.Create(ms);
        Message newMessage = Message.CreateMessage(reader, int.MaxValue, request.Version);
        newMessage.Properties.CopyProperties(request.Properties);
        request = newMessage;

    I suggest you refer link below to check whether it is related with encode.

    # WCF Extensibility – Message Inspectors

    https://blogs.msdn.microsoft.com/carlosfigueira/2011/04/18/wcf-extensibility-message-inspectors/

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, December 14, 2017 3:23 AM
  • Hi Tao Zhou,

    thank you.

    the exception stack trace is 

    <Exception>
    <ExceptionType>System.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
    <Message>This message cannot support the operation because it has been written.</Message>
    <StackTrace>
    at System.ServiceModel.Channels.Message.CreateBufferedCopy(Int32 maxBufferSize)
    at System.ServiceModel.Channels.Message.CreateBufferedCopy(Int32 maxBufferSize)
    at Library.Helper.Inspectors.MessageInspector.AfterReceiveRequest(Message&amp; request, IClientChannel channel, InstanceContext instanceContext)
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.AfterReceiveRequestCore(MessageRpc&amp; rpc)
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc)
    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)
    at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
    at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
    at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
    at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
    at System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
    at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
    at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
    at System.ServiceModel.Channels.SecurityChannelListener`1.ReceiveItemAndVerifySecurityAsyncResult`2.Start()
    at System.Runtime.ActionItem.DefaultActionItem.TraceAndInvoke()
    at System.Runtime.ActionItem.CallbackHelper.InvokeWithoutContext(Object state)
    at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
    at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
    at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
    </StackTrace>
    <ExceptionString>System.InvalidOperationException: This message cannot support the operation because it has been written.</ExceptionString>
    </Exception>

    not sure how I got CreateBufferedCopy twice.

    thank you,

    -Abraham


    • Edited by Abraham-D Thursday, December 14, 2017 1:40 PM
    Thursday, December 14, 2017 1:39 PM
  • Hi Abraham-D,

    Did you receive the same error with my above code to re-generate the message?

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, December 15, 2017 5:25 AM
  • Hi Tao Zhou,

    Not the same error. :) BTW your code will not recreate the message.

    thank you,

    -Abraham

    Friday, December 15, 2017 2:20 PM
  • Hi Abraham,

    What error did you get with my code?

    I am not sure whether you checked the link, the complete code is below:

    MemoryStream ms = new MemoryStream();
        XmlWriter writer = XmlWriter.Create(ms);
        request.WriteMessage(writer); // the message was consumed here
        writer.Flush();
        ms.Position = 0;
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(ms);
        this.ChangeMessage(xmlDoc);
     
        //Now recreating the message
        ms = new MemoryStream();
        xmlDoc.Save(ms);
        ms.Position = 0;
        XmlReader reader = XmlReader.Create(ms);
        Message newMessage = Message.CreateMessage(reader, int.MaxValue, request.Version);
        newMessage.Properties.CopyProperties(request.Properties);
        request = newMessage;

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, December 18, 2017 5:35 AM
  • Hi Tao Zhou,

    Thank you for your reply.

    The error message with the mentioned code is

    <s:Body u:Id="_1">
    	<s:Fault>
    		<s:Code>
    			<s:Value>s:MustUnderstand</s:Value>
    		</s:Code>
    		<s:Reason>
    			<s:Text xml:lang="en-US">The header 'Security' from the namespace 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' was not understood by the recipient of this message, causing the message to not be processed.  This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process.  Please ensure that the configuration of the client's binding is consistent with the service's binding. </s:Text>
    		</s:Reason>
    	</s:Fault>
    </s:Body>
    

    As I mentioned earlier, I am using a custom binding with mutualcertificate security. 

    thank you,

    -Abraham

    Monday, December 18, 2017 1:29 PM
  • Hi Abraham,

    >>I am using a custom binding with mutualcertificate security.

    Yes, I know that you are using mutual certificate security.

    For your original error, it is related with “This message cannot support the operation because it has been written”.

    For current error, it is related with “Please ensure that the configuration of the client's binding is consistent with the service's binding”.

    My above code only re-create the message, did you modify the message with certificate in “AfterReceiveRequest”?

    If you remove this Message Inspector, and make a test with “secure” endpoint address, will it work?

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, December 19, 2017 5:55 AM
  • Hi Tao Zhou,

    Thank you for looking into this issue.

    I am using the same client without any change.

    <service name="MyService" behaviorConfiguration="certBehavior">
            <endpoint address="" binding="customBinding" bindingConfiguration="notSecure01" contract="xxxx_Ext_PortType_V1_0" behaviorConfiguration="inspectorBehavior"/>
            <endpoint address="secure" binding="customBinding" bindingConfiguration="MutualCertBinding01" contract="xxxx_Ext_PortType_V1_0" behaviorConfiguration="inspectorBehavior" />
    </service>

    the same client will work if I change the end point to '<endpoint address="secure" binding="customBinding" bindingConfiguration="MutualCertBinding01" contract="xxxx_Ext_PortType_V1_0"/>'

    ie without the message inspector.

    the first endpoint '"notSecure01"' is working fine with SoapUI. the second endpoint (with certificate security) works fine with a WCF client without message inspector.

    The other unknown is, there are many monitoring services on that server like splunk etc. Do you think any of these services interact with the message Inspector?

    thank you,

    -Abraham

    Tuesday, December 19, 2017 1:33 PM
  • Hi Abraham,

    >>Do you think any of these services interact with the message Inspector?

    To check whether it is related with these services, you could host your WCF Service with message Inspector in a clean computer, and make a test again.

    Currently, there are two different errors while using MessageInspector.

    Will you receive any error with code below:

    public class MessageInspector : IDispatchMessageInspector
        {
            public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
            {           
                return null;
            }
        }

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, December 20, 2017 7:19 AM
  • Hi Tao Zhou,

    Sorry for the delay.

    That was the first test I did. 'AfterreceiveRequest with a return null'. that worked fine without any issue. 

    thank you,

    -Abraham

    Wednesday, December 27, 2017 2:33 PM
  • Hi Abraham,

    I am afraid it is difficult to analyze this issue without reproducing it.

    Could you share us a simple project and detail steps? Then, we could try to reproduce your issue.

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, December 28, 2017 2:49 AM