user2471435
user2471435

Reputation: 1674

Custom Client MessageInspector recording requests but not responses

I have a Custom ClientMessageInspector that records requests but not replies to my service.

The code is:

namespace MessageListener.Instrumentation
{
    public class MessageInspector : IClientMessageInspector
    {

        private Message TraceMessage(MessageBuffer buffer)
        {
            // Must use a buffer rather than the original message, because the Message's body can be processed only once.
            Message msg = buffer.CreateMessage();

            using (RREM_GilbaneEntities3 entities3 = new RREM_GilbaneEntities3())
            {
                SOAPMessage soapMessages = new SOAPMessage
                {
                    SOAPMessage1 = msg.ToString(),
                    created = DateTime.Now,
                    source = "Interface12",
                    sourceIP = "Interface12"
                };
                entities3.SOAPMessages.Add(soapMessages);
                entities3.SaveChanges();
            }

            //Return copy of origonal message with unalterd State
            return buffer.CreateMessage();
        }

        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
            reply = TraceMessage(reply.CreateBufferedCopy(int.MaxValue));
        }

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
        {
            request = TraceMessage(request.CreateBufferedCopy(int.MaxValue));
            return null;
        }
    }
}

What seems to be happening is both AfterRecievReply and BeforeSendRequest are being called. In AfterRecieveReply before I call TraceMessage, I can see the whole reply. Inside TraceMessage, when I do:

// Must use a buffer rather than the original message, because the Message's body can be processed only once.

        Message msg = buffer.CreateMessage();

it turns the reply into junk:

msg {<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header />
  <soap:Body>... stream ...</soap:Body>
</soap:Envelope>}

What's going on?

Upvotes: 0

Views: 186

Answers (1)

carlosfigueira
carlosfigueira

Reputation: 87238

The reply isn't a junk message - it's just when you call ToString on it that it doesn't show the body of the message. Remember that a message can only be consumed once; once its body is read, it cannot be read again. Since many places (including the watch window of debuggers) will call ToString on an object, this method is implemented in a way that if it doesn't know for sure that a message body can be read multiple times, then it won't, which seems to be your case. If you want to really write out the message, try using this code:

public string MessageToString(Message message) {
    using (MemoryStream ms = new MemoryStream()) {
        XmlWriterSettings ws = new XmlWriterSettings();
        ws.Encoding = new UTF8Encoding(false);
        using (XmlWriter w = XmlWriter.Create(ms)) {
            message.WriteMessage(w);
            w.Flush();
            return ws.Encoding.GetString(ms.ToArray());
        }
    }
}

Upvotes: 2

Related Questions