Search code examples
wcfmsmqnetmsmqbindingmsmq-wcfmsmq-transaction

Read WCF MSMQ Message from C#


I used a WCF client to send msmq message to WCF Service, before WCF Service process the msmq message, I want to check the body of the message.
After checking the content of msmq message body, I got below result.
enter image description here
But, I failed to get the exact string.
Below is definition of WCF Service

    [ServiceContract]
public interface IMSMQService
{

    [OperationContract(IsOneWay = true)]       

    void ShowMessage(string msg);
}

I used below method to retrieve message body, and it output empty, if I add watch on ms, I could get

"\0\u0001\0\u0001\u0004\u0002(net.msmq://vdi-v-tazho/private/TestQueue\u0003\aV\u0002\v\u0001s\u0004\v\u0001a\u0006V\bD\n\u001e\0��+http://tempuri.org/IMSMQService/ShowMessage@\u0017VsDebuggerCausalityData\bAhttp://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink�<��ϣ-lN��FoJ�0�u\u0006�\"\0\0\0\0\u0017�\0i8�C�I\7�^Q�A\u0012�w}\f�A�\u000f\rޮ�pe\0\t\0\0D\f\u001e\0��(net.msmq://vdi-v-tazho/private/TestQueue\u0001V\u000e@\vShowMessage\b\u0013http://tempuri.org/@\u0003msg�\u0004test\u0001\u0001\u0001"

                //message.Formatter = new XmlMessageFormatter(new String[] { });
            //StreamReader sr = new StreamReader(message.BodyStream);
            string ms = "";
            //while (sr.Peek() >= 0)
            //{
            //    ms += sr.ReadLine();
            //}
            message.Formatter = new ActiveXMessageFormatter();
            string result = System.Text.Encoding.UTF8.GetString(message.Body as byte[]);
            StreamReader reader = new StreamReader(message.BodyStream);

            ms = reader.ReadToEnd();
            MessageBox.Show(ms);

Solution

  • I got below code to achieve my requirement.

    private void MSMQStringBody_Click(object sender, EventArgs e)
    {
        System.Messaging.MessageQueue[] queueList = System.Messaging.MessageQueue.GetPrivateQueuesByMachine(Environment.MachineName);
        MessageQueue myQueue = queueList[1];
        List<System.Messaging.Message> messages = myQueue.GetAllMessages().ToList();
        foreach (System.Messaging.Message message in messages)
        {
            System.Xml.XmlDocument result = ConvertToXMLDoc(message);
            MessageBox.Show(result.InnerText);
        }
    
    }
    public System.Xml.XmlDocument ConvertToXMLDoc(System.Messaging.Message msg)
    {
        byte[] buffer = new byte[msg.BodyStream.Length];
        msg.BodyStream.Read(buffer, 0, (int)msg.BodyStream.Length);
        int envelopeStart = FindEnvolopeStart(buffer);
        System.IO.MemoryStream stream = new System.IO.MemoryStream(buffer, envelopeStart, buffer.Length - envelopeStart);
        System.ServiceModel.Channels.BinaryMessageEncodingBindingElement elm = new System.ServiceModel.Channels.BinaryMessageEncodingBindingElement();
        System.ServiceModel.Channels.Message msg1 = elm.CreateMessageEncoderFactory().Encoder.ReadMessage(stream, Int32.MaxValue);
        System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
        doc.Load(msg1.GetReaderAtBodyContents());
        msg.BodyStream.Position = 0;
        return doc;
    }
    private int FindEnvolopeStart(byte[] stream)
    {
        int i = 0;
        byte prevByte = stream[i];
        byte curByte = (byte)0;
        for (i = 0; i < stream.Length; i++)
        {
            curByte = stream[i];
            if (curByte == (byte)0x02 &&
            prevByte == (byte)0x56)
                break;
            prevByte = curByte;
        }
        return i - 1;
    }