Problem with receiving messages from MSMQ

Hi I have a C# application that pumps messages into MSMQ and Navision is supposed to pick them. Navision picks up the messages but they get truncated. When I see the message body from MSMQ it is 3C 3F 78 6D 6C 20 76 65 72 <?xml ver 73 69 6F 6E 3D 22 31 2E 30 sion="1.0 22 3F 3E 0D 0A 3C 73 74 72 "?>…<str 69 6E 67 3E 54 65 73 74 20 ing>Test 4D 65 73 73 61 67 65 3C 2F Message</ 73 74 72 69 6E 67 3E string> However, when I try to retrieve the message from Navision, the message just reads <?xml version="1.0"?> and nothing else. Can anybody please let me know whats wrong? My Navision codes are: OnRun() CREATE(Comcom); CREATE(MSMQBus); MSMQBus.OpenReceiveQueue(’.\Private$\aviprivq’,1,1); Comcom.AddBusAdapter(MSMQBus,1); Comcom::MessageReceived(VAR InMessage : Automation “’’.IDISPATCH”) InMsg := InMessage; InStr := InMsg.GetStream; InStr.READTEXT(Line,500); MESSAGE(Line);

Err, umm – not an MSMQ expert, but I do know that InStream.READTEXT reads ‘the next line’ of the stream – it stops when it finds the CR/LF. So, don’t you need to do something like:WHILE NOT InStr.EOS DO BEGIN InStr.READTEXT(Line,500); MESSAGE(Line); END;


Originally posted by avi

OnRun() CREATE(Comcom); CREATE(MSMQBus); MSMQBus.OpenReceiveQueue('.\Private$\aviprivq',1,1); Comcom.AddBusAdapter(MSMQBus,1); Comcom::MessageReceived(VAR InMessage : Automation "''.IDISPATCH") InMsg := InMessage; InStr := InMsg.GetStream; InStr.READTEXT(Line,500); MESSAGE(Line);

With READTEXT you read the text out of a file/instream, and you are trying to get an XML document out of the instream. If you’d just use an XML DOM object instead of trying to access the instream directly, you can just load the instream into the DOM and use that instead. Comcom::MessageReceived(VAR InMessage : Automation "''.IDISPATCH") InMsg := InMessage; InS := InMsg.GetStream(); // load the instream into a new XML DOM object IF NOT ISCLEAR(MSDOM) THEN CLEAR(MSDOM); IF NOT CREATE(MSDOM) THEN ERROR(DOM_NOT_CREATED); IF NOT MSDOM.load(InS) THEN ERROR(XML_NOT_LOADED); By the way, the MSDOM is an automation type variable subtype “‘Microsoft XML, v3.0’.DOMDocument30”. HTH, Daniel

Thanks a lot Daniel, the XML DOM object is what I actually needed. I can now insert and modify records in a Table from an external application using MSMQ. Avi.

Cool, glad I could help :slight_smile:

avi, I’ve come a long way since my posting of the NAS tutorial on MIBUSO. I have a working NAS/XML add-on. Using an XML DOM was my final solution. Here is the code I used to run my NAS XML message queuefrom my NAS startup codeunit. I use a table to map nodes to tables and fields and in the ParseXML function of the XML Functions codeunit I run thru the XML node by node by attribute. If you’d like to talk about this some more please feel free to email me… ***** I added some code to the NASHandler function (99) in codeunit 1 ApplicationManagement (v3.60): NASHandler(ATASID : Text[260]) ATASStarted := FALSE; ParamStr := UPPERCASE(ATASID); REPEAT SepPosition := STRPOS(ParamStr,’,’); IF SepPosition > 0 THEN Parameter := COPYSTR(ParamStr,1,SepPosition - 1) ELSE Parameter := COPYSTR(ParamStr,1); CASE Parameter OF ‘CG’: BEGIN BizTalkATASStartup.RUN; ATASStarted := TRUE; END; ‘MAILLOG’: BEGIN CODEUNIT.RUN(CODEUNIT::“E-Mail Dispatcher”); ATASStarted := TRUE; END; ‘XML’: //Begin added code Make sure the set the startup parameter of the NAS service to XML BEGIN CODEUNIT.RUN(CODEUNIT::“XML Appln. Srv. Start”); ATASStarted := TRUE; END; //End added code ‘ADCS’: BEGIN ADCSATASStartup.SetNASID(COPYSTR(ParamStr,SepPosition + 1)); ADCSATASStartup.RUN; ATASStarted := TRUE; END; END; ParamStr := COPYSTR(ParamStr,SepPosition + 1); UNTIL SepPosition = 0; IF NOT ATASStarted THEN BEGIN CPApplnSrvMgt.SetNASID(ATASID); WORKDATE := 0D; IF CPApplnSrvSetup.GET(ATASID) THEN BEGIN IF CPApplnSrvMgt.GetSendMail THEN BEGIN MailHandler.RUN; MailHandler.StartCountDown(2000); END; IF CPApplnSrvMgt.GetPerformSynch THEN MsgDispatcher.RUN; IF CPApplnSrvMgt.GetPerformRequests THEN RequestHandler.RUN; END ELSE ERROR(Text018,CPApplnSrvSetup.TABLECAPTION,ATASID); END; Global Variables: Name DataType Subtype/Length ComcomIn Automation ‘Navision Communication Component version 2’.CommunicationComponent MQBusIn Automation ‘Navision MS-Message Queue Bus Adapter’.MSMQBusAdapter XMLFunctions Codeunit XML Functions XMLSetup Record XML Setup OnRun() //This code should be set to be executed when the NAS is first run IF ISCLEAR(ComcomIn) THEN BEGIN CREATE(ComcomIn); IF ISCLEAR(MQBusIn) THEN CREATE(MQBusIn); XMLSetup.GET; MQBusIn.OpenReceiveQueue(XMLSetup.“MSMQ Name - Incoming”,1,1); //ex… ‘.\private$\myqueue’ ComcomIn.AddBusAdapter(MQBusIn,1); END; ComcomIn::MessageReceived(VAR InMessage : Automation “’’.IDISPATCH”) //This special function is created when the global variable //ComcomIn [Automation ‘Navision Communication Component version 2’.CommunicationComponent] //is defined InMessage1 := InMessage; CREATE(xmlin); InStrm := InMessage1.GetStream; xmlin.load(InStrm); //This a for debugging, it will write out to a //text file whatever XML is in the XML DOM being imported from the queue XMLSetup.GET; IF (XMLSetup.“Write Out Imported XML”) AND (XMLSetup.“XML Save Folder” <> ‘’) THEN BEGIN FileName := DELCHR(DELCHR(FORMAT(TODAY),’=’,’/’)+FORMAT(TIME)+’.xml’,’=’,’ ,:’);“XML Save Folder” + FileName); END; InMessage1.CommitMessage(); //The XMLFunctions is a codeunit for decoding/parsing the imported XML XMLFunctions.ParseXML(xmlin); ComcomIn Function Local Variables: Name DataType Subtype/Length InMessage1 Automation ‘Navision Communication Component version 2’.InMessage xmlin Automation ‘Microsoft XML, v3.0’.DOMDocument InStrm InStream OutStrm OutStream XMLFunctions Codeunit XML Functions FileName Text 30 *****