Error “This message cannot support the operation because it has been read”

前端 未结 3 1209
误落风尘
误落风尘 2020-12-30 02:29

I have the same problem that is listed in the following thread.

WSDL first WCF server where client does not send SOAPAction

I performed the steps that are li

相关标签:
3条回答
  • 2020-12-30 03:00

    You should use MessageBuffer.CreateMessage:

    The body of a Message instance can only be consumed or written once. If you wish to consume a Message instance more than once, you should use the MessageBuffer class to completely store an entire Message instance into memory.

    http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.messagebuffer.aspx

    Code from my current project:

    public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
    {
        MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);
        reply = buffer.CreateMessage();
        Message m = buffer.CreateMessage();
        LogMessage(m, " Response => ");
    }
    

    Add ref for Message param and return new message.

     private Message CreateMessageCopy(ref Message message, XmlDictionaryReader body)
    {
    ...
       message = buffer.CreateMessage();
    
    0 讨论(0)
  • 2020-12-30 03:05

    I had a very similar issue, using code from WCF Samples (RouteByBody to be precise) as well, and was able to solve it in a different way so I'll post it here in case it helps anybody.

    Situation: The client application (consumer) would work in Release, however, when the debugger was attached it would always fail with the error "This message cannot support the operation because it has been read".

    After much tracing and logging WCF messages, the only solution that worked for me turned out to be so simple:

    My Service was hosted on IIS, and with debug="true" in the <compilation> section of the web.config.

    Changing it to debug="false" on the service fixed all my problems.

    0 讨论(0)
  • 2020-12-30 03:06

    Dmitry Harnitski's answer does not work if you are debugging the service (It will give you a "This message cannot support the operation because it has been copied." error.)

    This works even in debug mode:

    XmlDictionaryReader GetReader(ref Message message)
    {
        MessageBuffer buffer = message.CreateBufferedCopy(Int32.MaxValue);
        message = buffer.CreateMessage();
        newMessage = buffer.CreateMessage();
        XmlDictionaryReader rv = buffer.CreateMessage().GetReaderAtBodyContents();
        buffer.Close();
        return rv;
    }
    
    static System.ServiceModel.Channels.Message newMessage = null;
    static System.ServiceModel.Channels.Message lastMessage = null;
    
    public string SelectOperation(ref System.ServiceModel.Channels.Message message)
    {
        try
        {
            if(message == lastMessage)
                message = newMessage;
    
            XmlDictionaryReader bodyReader = GetReader(ref message);
    
            lastMessage = message;
    
            XmlQualifiedName lookupQName = new XmlQualifiedName(bodyReader.LocalName, bodyReader.NamespaceURI);
            if (dispatchDictionary.ContainsKey(lookupQName))
            {
                return dispatchDictionary[lookupQName];
            }
            else
            {
                return null;
            }
        }
        catch(Exception ex)
        {
            throw ex;
        }
    }
    
    0 讨论(0)
提交回复
热议问题