Welcome to WebmasterWorld Guest from 54.163.49.19

Forum Moderators: ocean10000

Message Too Old, No Replies

Deserializing Navision message in MSMQ

.net newbie using Visual Basic and MSMQ

     
1:11 pm on Apr 21, 2010 (gmt 0)

Full Member

10+ Year Member

joined:Oct 14, 2004
posts:316
votes: 0


I am new to asp.net 3.5 - but have managed to create a website which works well. Now, however, I need to send a non-transactional message, asking for a response, to MSMQ Private Me - and thereby to Navision - and read the response to a label. From various tests, I know I can send the message and get the response, but de-serializing it is another matter altogether.

From looking at a test response message in Private Queues
I know that the response comes in this format:

FF FE 3C 00 3F 00 78 00 <.?.x.

6D 00 6C 00 20 00 76 00 m.l. .v.

65 00 72 00 73 00 69 00 e.r.s.i.

6F 00 6E 00 3D 00 22 00 o.n.=.".

31 00 2E 00 30 00 22 00 1...0.".

20 00 65 00 6E 00 63 00 .e.n.c.

6F 00 64 00 69 00 6E 00 o.d.i.n.

67 00 3D 00 22 00 55 00 g.=.".U.

54 00 46 00 2D 00 31 00 T.F.-.1.

36 00 22 00 20 00 73 00 6.". .s.

74 00 61 00 6E 00 64 00 t.a.n.d.

61 00 6C 00 6F 00 6E 00 a.l.o.n.

65 00 3D 00 22 00 6E 00 e.=.".n.

6F 00 22 00 3F 00 3E 00 o.".?.>.

0D 00 0A 00 3C 00 58 00 ....<.X.

4D 00 4C 00 3E 00 0D 00 M.L.>...

0A 00 09 00 3C 00 42 00 ....<.B.

75 00 73 00 69 00 6E 00 u.s.i.n.

65 00 73 00 73 00 4F 00 e.s.s.O.

62 00 6A 00 65 00 63 00 b.j.e.c.

74 00 3E 00 67 00 65 00 t.>.g.e.

74 00 61 00 74 00 74 00 t.a.t.t.

72 00 69 00 62 00 75 00 r.i.b.u.

74 00 65 00 73 00 3C 00 t.e.s.<.

2F 00 42 00 75 00 73 00 /.B.u.s.

69 00 6E 00 65 00 73 00 i.n.e.s.

73 00 4F 00 62 00 6A 00 s.O.b.j.

65 00 63 00 74 00 3E 00 e.c.t.>.

0D 00 0A 00 09 00 3C 00 ......<.

41 00 74 00 74 00 72 00 A.t.t.r.

69 00 62 00 75 00 74 00 i.b.u.t.

65 00 73 00 3E 00 0D 00 e.s.>...

0A 00 09 00 09 00 3C 00 ......<.

43 00 6F 00 64 00 65 00 C.o.d.e.

3E 00 42 00 4F 00 54 00 >.B.O.T.

54 00 4F 00 4D 00 42 00 T.O.M.B.

4F 00 58 00 52 00 4F 00 O.X.R.O.

4C 00 4C 00 45 00 52 00 L.L.E.R.

53 00 49 00 5A 00 45 00 S.I.Z.E.

3C 00 2F 00 43 00 6F 00 <./.C.o.

64 00 65 00 3E 00 0D 00 d.e.>...

0A 00 09 00 09 00 3C 00 ......<.

44 00 65 00 73 00 63 00 D.e.s.c.

72 00 69 00 70 00 74 00 r.i.p.t.

69 00 6F 00 6E 00 3E 00 i.o.n.>.

42 00 6F 00 74 00 74 00 B.o.t.t.

6F 00 6D 00 20 00 42 00 o.m. .B.

6F 00 78 00 2F 00 52 00 o.x./.R.

6F 00 6C 00 6C 00 65 00 o.l.l.e.

72 00 20 00 53 00 69 00 r. .S.i.

7A 00 65 00 3C 00 2F 00 z.e.<./.

44 00 65 00 73 00 63 00 D.e.s.c.

72 00 69 00 70 00 74 00 r.i.p.t.

69 00 6F 00 6E 00 3E 00 i.o.n.>.

0D 00 0A 00 09 00 3C 00 ......<.

2F 00 41 00 74 00 74 00 /.A.t.t.

72 00 69 00 62 00 75 00 r.i.b.u.

74 00 65 00 73 00 3E 00 t.e.s.>.

0D 00 0A 00 3C 00 2F 00 ....<./.

58 00 4D 00 4C 00 3E 00 X.M.L.>.

0D 00 0A 00 ....




which throws me. I have tried out various ideas - I know the response can work with a COM object, but that is very slow, so I tried:


Try
' open the receive queue
ResponseQueue = New _
MessageQueue(".\private$\privateout")
ResponseQueue.Formatter = New ActiveXMessageFormatter()
ResponseQueue.MessageReadPropertyFilter.SetAll()
Dim msg As New Message
msg = ResponseQueue.Receive()
msg.Formatter = New ActiveXMessageFormatter()
Dim myObject As Object
'type cast the message Body to Object Type
myObject = DirectCast(msg.Body, Object)
Dim xmlDoc As New System.Xml.XmlDocument()
'load the xml string using XmlDOCument
xmlDoc.LoadXml(myObject.ToString())
Dim description As XmlNodeList = xmlDoc.GetElementsByTagName("Description")
Label2.Text = description.Item(0).InnerXml


Catch ex As Exception
Label2.Text = ("Generic Exception was thrown: " _
& ex.Source & ": " & ex.Message)
End Try


But that got me the exception: System.Messaging: Cannot deserialize the message passed as an argument. Cannot recognize the serialization format.

I am very stuck - and would greatly appreciate some advice.
1:58 pm on Apr 21, 2010 (gmt 0)

Administrator

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month

joined:Jan 14, 2004
posts:852
votes: 0


It looks like a UTF8 Encoded xml stream, with a few bytes upfront for length I am guessing. You might be able to read it in as a binary, skiping the initial bytes till you reach the first <, then dump it into an xml reader for further processing.

What type of application is filling the message Que a dot.net application or something else?
2:50 pm on Apr 21, 2010 (gmt 0)

Full Member

10+ Year Member

joined:Oct 14, 2004
posts:316
votes: 0


Thanks for coming back to me. The response queue is being filled by Microsoft Navsion.

I had a look at the binary formatter - I tried

Try
' open the receive queue
ResponseQueue = New _
MessageQueue(".\private$\privateout")
ResponseQueue.Formatter = New System.Messaging.BinaryMessageFormatter()
ResponseQueue.MessageReadPropertyFilter.SetAll()
Dim msg As New Message
msg = ResponseQueue.Receive(New TimeSpan(0, 0, 30))
Label2.Text = msg.Body
Catch ex As Exception
Label2.Text = ("Generic Exception was thrown: " _
& ex.Source & ": " & ex.Message)
End Try


Which I thought would convert the message body more or less as is into a label as text. The idea was to go one step at a time - refine into xmlreader and then filter once I knew I had something to handle. But once again I got System.Messaging: Cannot deserialize the message passed as an argument. Cannot recognize the serialization format.
1:59 pm on Apr 22, 2010 (gmt 0)

Administrator

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month

joined:Jan 14, 2004
posts:852
votes: 0


Have you tried using the BodyStream object, which returns the result as a stream. Which I think will bypass the serialization problems, from what I am reading.

Message.BodyStream Property [msdn.microsoft.com]
10:00 am on May 4, 2010 (gmt 0)

Full Member

10+ Year Member

joined:Oct 14, 2004
posts:316
votes: 0


As far as I can figure that, that seems to apply to sending a message, rather then deserializing a message on receipt.
2:26 pm on May 4, 2010 (gmt 0)

Administrator

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month

joined:Jan 14, 2004
posts:852
votes: 0


That is its primary use correct. But it might work for you to get raw access to the actual contents to work with the way you want to.
1:16 pm on June 21, 2010 (gmt 0)

Full Member

10+ Year Member

joined:Oct 14, 2004
posts: 316
votes: 0


I couldn't find a way of using the BodyStream object satisfactorily. Bearing in mind that Navision vendor's experience of handling the message queue has been with a COM object, I wondered if my problem was related to this. I therefore tried:

Dim msg As New Message
msg = ResponseQueue.Receive()
Try
Dim formattedMessage As String
Try
msg.Formatter = New XmlMessageFormatter(New Type() {GetType(String)})
formattedMessage = msg.Body.ToString()
' allow interoperability with applications that use the MSMQ COM control
Catch generatedExceptionName As InvalidOperationException
msg.Formatter = New ActiveXMessageFormatter()
formattedMessage = CStr(msg.Body)
End Try
Label2.Text = formattedMessage

Catch ex As Exception
Label2.Text = ("Generic Exception was thrown: " & _
ex.Source & ": " & ex.Message)
End Try

But I was still unable to deserialize the code.

I then thought about the binary suggestion made in a post above, and tried

Dim msg As New Message
msg = ResponseQueue.Receive()
Try
Dim formattedMessage As String
msg.Formatter = New BinaryMessageFormatter()
formattedMessage = msg.Body.ToString()
Label2.Text = formattedMessage
Catch ex As Exception
Label2.Text = ("Generic Exception was thrown: " & _
ex.Source & ": " & ex.Message)
End Try

Somewhat to my surprise, I still got the error messages: Cannot deserialize the message passed as an argument. Cannot recognize the serialization format.

Struggling with this one.