Tomas
Tomas

Reputation: 18107

MSMQ and ProtoBuf-Net serialization c#

I have a class with many properties, one of them are byte[] property. I would like to send this class to another server using MSMQ. But before sending it I would like to serialize it using ProtoBuf-Net. Is it possible to attach ProtoBuf-Net serializer to MSMQ?

Frankly speaking I do not understand how to send class to queue. I have tried to use code below to put class to MSMQ queue but got exception "There was an error generating the XML document."

EntityBase is a class which I would like to send. Previously I have used my own File System based messaging system and ProtoBuf-Net to serialize class.

const string queueName = @".\private$\TestQueue";

private static void SendMessageToQueue(EntityBase entity)
{
    // check if queue exists, if not create it
    MessageQueue msMq = null;
    if (!MessageQueue.Exists(queueName))
    {
        msMq = MessageQueue.Create(queueName);
    }
    else
    {
        msMq = new MessageQueue(queueName);
    }
    try
    {

        msMq.Send(entity);
    }
    catch (MessageQueueException ee)
    {
        Console.Write(ee.ToString());
    }
    catch (Exception eee)
    {
        Console.Write(eee.ToString());
    }
    finally
    {
        msMq.Close();
    }
    Console.WriteLine("Message sent ......");
}

Upvotes: 2

Views: 979

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062820

My advice would be: send either a string or a byte[] as the message; you can do this as:

byte[] body;
using(var ms = new MemoryStream()) {
    Serializer.Serialize(ms, entity);
    body = ms.ToArray();
}

and then Send(body), or if you want a string, then Send(Convert.ToBase64String(body)). And reverse this as the other end.

There looks to also be a mechanism for passing a Message along with an IMessageFormatter, but I'm not sure it is worth it. Example of reading:

Message msg = // receive
byte[] body = (byte[])msg.Body;
EntityBase entity;
using(var ms = new MemoryStream(body)) {
    entity = Serializer.Deserialize<EntityBase>(ms);
}

or (if choosing to pass a string):

string base64 = (string)msg.Body;
byte[] body = Convert.FromBase64String(base64);
// as before

Upvotes: 3

Related Questions