Problem with receiving MSMQ message body

Kaitsu
Member Posts: 22
Sending MSMQ messages works just fine with 'Microsoft Message Queue 3.0 Object Library' automation object but there are problems with the body of received message which always seems to be empty. Neither DOMDocument type body nor text type body does not seem to work. I am using the following code to receive the message:
varTransaction := 0;
varWantDestinationQueue := 0;
varWantBody := 1;
varReceiveTimeOut := 30000;
varWantConnectorType := 0;
ReceiveMessage := ReceiveQueue.Receive(
varTransaction,
varWantDestinationQueue,
varWantBody,
varReceiveTimeOut,
varWantConnectorType);
varTransaction := 0;
varWantDestinationQueue := 0;
varWantBody := 1;
varReceiveTimeOut := 30000;
varWantConnectorType := 0;
ReceiveMessage := ReceiveQueue.Receive(
varTransaction,
varWantDestinationQueue,
varWantBody,
varReceiveTimeOut,
varWantConnectorType);
0
Comments
-
your ReceiveMessage object is empty? Have you verified that the message has a value in the queue itself? You're looking for the ReceiveMessage.Body object, which is a variant. Load the body into an MSDOM object (MSDOM.LoadXML(FORMAT(Message.Body))) should work.0
-
I have verified that there is value in message by enabling queue journal.
When reading MSDOM object (I am using 'Microsoft XML, v3.0'.DOMDocument Automation variable) with FORMAT(Message.Body)) gives the following error:
"This data type is not supported by C/SIDE. You can access data from any of the following data types VT_VOID, VT_I2,..."
Reading text variant with FORMAT(Message.Body)) just gives an empty string.0 -
I tried to compress the code, assuming that the body is a text type variant. Here's a more complete code snippet:
CREATE(MSDOM); MyVariant := MyMessage.Body; IF MyVariant.ISTEXT THEN // use LoadXML when you have a string to load MSDOM.loadXML(MyVariant) ELSE // use Load if you have another object type to load MSDOM.load(MyVariant); CLEAR(MSDOM);
MSDOM is 'Microsoft XML, v3.0'.DOMDocument30
MyMessage is 'Microsoft Message Queue 3.0 Object Library'.MSMQMessage
If this doesn't work then I'd suggest you revise the code that sends the message to make sure the body of the message body contains either a string or an MSDOM object.0 -
It just does not work.
If body is text (In computer management / message queuing it looks like this: 54 00 45 00 53 00 54 00 T.E.S.T.) I don't get any errors. After loadXML(MyVariant) I try MSDOM.Save but I only get empty xml file.
If body is xml object like this
(
11 0F D9 F6 73 9C D3 11 B3 ..ÙösœÓ.³
2E 00 C0 4F 99 0B B4 3C 78 ..ÀO™.´<x
6D 6C 3E 3C 6F 75 74 3E 3C ml><out><
6C 6F 63 61 74 69 6F 6E 3E location>
3C 78 63 6F 6F 72 64 3E 33 <xcoord>3
33 32 38 34 33 33 3C 2F 78 328433</x
63 6F 6F 72 64 3E 3C 79 63 coord><yc
6F 6F 72 64 3E 36 38 32 35 oord>6825
30 35 31 3C 2F 79 63 6F 6F 051</ycoo
72 64 3E 3C 2F 6C 6F 63 61 rd></loca
74 69 6F 6E 3E 3C 2F 6F 75 tion></ou
74 3E 3C 2F 78 6D 6C 3E 0D t></xml>.
0A) .
I get the following error with load:
"Could not invoke the member load.... The number of elements provided is different from the number of arguments accepted by the method or property".0 -
It might error out at the "ÙösœÓ.³" part, which does not look like XML to me. Do you have any control over what is sent into the queue? Maybe you can try to send the XML as a string.
The dots between the letters is because the text string is encoded as a double byte character stream, and the LoadXML method should be able to handle that.0 -
Messages are sent using C++ program and MSXML::IXMLDOMDocumentPtr and IMSMQMessagePtr
Actually it looks like MyVariant is always empty no matter what I send to the queue.
I can send xml as double byte text but MyVariant is still empty.0 -
That program must use the same object type, or it will fail. I'm not a C++ programmer at all, but the 'Microsoft XML, v3.0'.DOMDocument30 should be available in there as well. I would probably take this question into a C++ forum and ask what type to use.0
-
It would be enough if just simple string came through. No need for xml really. But either body of the message is empty or assigning it to variant fails.0
-
Just as an example:
If you set a SQL Server field to data type text, Navision will not recognize it. You try to assign a SQL Server type text to a text field in NAV, it will error out.
I know there are many types of strings in C++, and you're going to have to try each one of them until you find the one that NAV recognizes as a text variable. Then, you can put XML inside the string and load it into an MSDOM object using the LoadXML method.0 -
Even when I send a string from Navision and then read it the body is empty. I am using the following code:
IF ISCLEAR(SendQueueInfo) THEN CREATE(SendQueueInfo); IF ISCLEAR(ReceiveQueueInfo) THEN CREATE(ReceiveQueueInfo); IF ISCLEAR(DOMDocument) THEN CREATE(DOMDocument); ReceiveQueueInfo.PathName := '.\PRIVATE$\queue'; ReceiveQueueInfo.Create(); ReceiveQueue := ReceiveQueueInfo.Open(1, 0); // 1 = Receive access, 0 = Deny none SendQueueInfo.PathName := '.\PRIVATE$\queue'; SendQueue := SendQueueInfo.Open(2, 0); // 2 = Send access, 0 = Deny none IF ISCLEAR(SendMessage) THEN CREATE(SendMessage); // Send SendMessage.Body := 'test'; SendMessage.ResponseQueueInfo := ReceiveQueueInfo; SendMessage.Send(SendQueue); // Receive varTransaction := 0; varWantDestinationQueue := 0; varWantBody := 1; varReceiveTimeOut := 30000; varWantConnectorType := 0; ReceiveMessage := ReceiveQueue.Receive( varTransaction, varWantDestinationQueue, varWantBody, varReceiveTimeOut, varWantConnectorType); MyVariant := ReceiveMessage.Body; IF MyVariant.ISTEXT THEN BEGIN MESSAGE(FORMAT(ReceiveMessage.Body)); MESSAGE(FORMAT(MyVariant)); END ELSE MESSAGE('Not text'); ReceiveQueueInfo.Delete();
0 -
Oops... The problem was with the Receive function parameters. They were like this:
varTransaction := 0;
varWantDestinationQueue := 0;
varWantBody := 1;
varWantConnectorType := 0;
[-X
when they should have been like this:
varTransaction := false;
varWantDestinationQueue := false;
varWantBody := true;
varWantConnectorType := false;
Thanks for the help anyway. It works now. \:D/0 -
You know I didn't even look at those :oops:
Good job making that work.0 -
There is one more problem with receiving messages. You need to verify that received message is the reply for the query you send. It should work like this:
REPEAT
ReceiveMessage := ReceiveQueue.Receive(
varTransaction,
varWantDestinationQueue,
varWantBody,
varReceiveTimeOut,
varWantConnectorType);
UNTIL ReceiveMessage.CorrelationId = SendMessage.Id;
But code above does not work because Ids that are variants cannot be compared with = operator. Is there a way to compare them in Navision? (FORMAT() does not work.)0 -
Put the value into a Variant type variable and use the functions. for instance:
IF MyVariant.ISTEXT THEN MyText := MyVariant;
You might be able to do something like:CASE TRUE OF MyVariant.ISTEXT: MyText := MyVariant; MyVariant.ISINTEGER: MyInteger := MyVariant; ELSE ERROR('incompatible data type'); END;
I haven't tested the second code snippet, but that's how I'd start out.0 -
The problem is that it is neither text nor integer type.0
-
Well text and integers are not the only datatypes supported in a Variant variable. It was a code snippet, an example to look at and expand on yourself. Open your object browser and see what other types are available.0
-
I mean none of the ISTEXT, ISINTEGER, ISAUTOMATION etc. functions available returns true.0
-
Then like I said before, you will have to find a data type to use in the C++ code that is compatible with a Navision data type.0
-
Message id is given internally in 'Microsoft Message Queue 3.0 Object Library'.MSMQMessage object and i just heard it is of type array of bytes.
So i guess 'correlation id' must be handled somehow within the xml object in the message body then...0
Categories
- All Categories
- 73 General
- 73 Announcements
- 66.6K Microsoft Dynamics NAV
- 18.7K NAV Three Tier
- 38.4K NAV/Navision Classic Client
- 3.6K Navision Attain
- 2.4K Navision Financials
- 116 Navision DOS
- 851 Navision e-Commerce
- 1K NAV Tips & Tricks
- 772 NAV Dutch speaking only
- 617 NAV Courses, Exams & Certification
- 2K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 320 Dynamics CRM
- 111 Dynamics GP
- 10 Dynamics SL
- 1.5K Other
- 990 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 35 Design Patterns (General & Best Practices)
- 1 Architectural Patterns
- 10 Design Patterns
- 5 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1.1K General Chat
- 1.6K Website
- 83 Testing
- 1.2K Download section
- 23 How Tos section
- 252 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions