XMLPORT.IMPORT fails while using with webservice
gdkve9
Member Posts: 161
Hi guys,
I am stuck at one point while using XMLPORTS. I have created an XMLPORT and a Codeunit for importing the data from an xml file. When I run the Codeunit locally, the data gets imported and everything looks fine.
The problem is, when I try to run the same Codeunit using Web Service, the XMLPORT.IMPORT function fails and returns the exception "Import Unsuccessful". Any ideas resolving the same would be highly appretiated.
Awaiting on the responses. Thanks in advance.
Following is the code that I am using for Import.
SendOrderDetails() FileExists : Boolean
IF EXISTS('C:\inetpub\wwwroot\Import Files\OrderDetails.xml') THEN
BEGIN
IF TestFile.OPEN('C:\inetpub\wwwroot\Import Files\OrderDetails.xml') THEN
BEGIN
TestFile.CREATEINSTREAM(VarInStream);
IF XMLPORT.IMPORT(50007,VarInStream) THEN
FileExists := TRUE
ELSE
ERROR('Import Unsuccessful');
END ELSE
ERROR('Error Opening file');
TestFile.CLOSE;
END ELSE
FileExists := FALSE;
I am stuck at one point while using XMLPORTS. I have created an XMLPORT and a Codeunit for importing the data from an xml file. When I run the Codeunit locally, the data gets imported and everything looks fine.
The problem is, when I try to run the same Codeunit using Web Service, the XMLPORT.IMPORT function fails and returns the exception "Import Unsuccessful". Any ideas resolving the same would be highly appretiated.
Awaiting on the responses. Thanks in advance.
Following is the code that I am using for Import.
SendOrderDetails() FileExists : Boolean
IF EXISTS('C:\inetpub\wwwroot\Import Files\OrderDetails.xml') THEN
BEGIN
IF TestFile.OPEN('C:\inetpub\wwwroot\Import Files\OrderDetails.xml') THEN
BEGIN
TestFile.CREATEINSTREAM(VarInStream);
IF XMLPORT.IMPORT(50007,VarInStream) THEN
FileExists := TRUE
ELSE
ERROR('Import Unsuccessful');
END ELSE
ERROR('Error Opening file');
TestFile.CLOSE;
END ELSE
FileExists := FALSE;
Dilip
Falling down is not a defeat..defeat is when you refuse to get up.
Falling down is not a defeat..defeat is when you refuse to get up.
0
Comments
-
A XML-Port look for 'C:\inetpub\wwwroot\Import Files\OrderDetails.xml' at the server where the service tier is running. So when you try to run this code it won't find the path because it is not there.
You can use the UPLOAD function to copy the file to a temp folder on the service tier and try to import it from there (store the path in a variable).0 -
I recommend do not use XML file stored on a disk (if it is possible). Be sure a function in the published codeunit can have parameter - type XMLport. In this case you can use this simple code in codeunit (InsertIncident is name of published method):
InsertIncident(VAR parXmlPort : XMLport XMLport50015)
parXmlPort.IMPORT();0 -
Hi Ploeg,
Thanks for the response.
I guess, that should not be the problem based on below two assumptions.
1. The TESTFILE.OPEN function returns true in the same code, which means it is able to open the file from the path. It just fails when calling the IMPORT function of the XMLPort after the xml file has been read from the path and hence throws the exception "Import Unsuccess". If there is problem in finding the path, the exception should have been "Error Opening File" which is mentioned as error msg in the sample code.
2. Secondly, I am using the following code for export which works fine with the webservice call.
TestFile.CREATE('C:\inetpub\wwwroot\Export Files\LoginDetails.xml');
TestFile.CREATEOUTSTREAM(TestStream);
XMLPORT.EXPORT(50004,TestStream);
TestFile.CLOSE;
Thanks again.Dilip
Falling down is not a defeat..defeat is when you refuse to get up.0 -
It is indeed the IMPORT function that is the trouble. IMPORT and EXPORT are two completely different things.
You could try the following code:LOCAL VARS: XMLFile -> File XMLStream -> InStream lPath -> Text (500) lCduCommonDialogManagement -> Codeunit (Common Dialog Management) ConfPersMgt -> Codeunit (Conf./Personalization Mgt.) TempFile -> File Filename -> File TEXT CONSTANT: LTXT_Filter -> XML files (*.xml)|*.xml|All files (*.*)|*.* IF ISSERVICETIER THEN BEGIN TempFile.CREATETEMPFILE; lPath := TempFile.NAME + '.xml'; TempFile.CLOSE; IF UPLOAD('Import XML', '',LTXT_Filter,'',lPath) THEN BEGIN XMLFile.OPEN(lPath); XMLFile.CREATEINSTREAM(XMLStream); XMLPORT.IMPORT([YOUR IMPORT], XMLStream); XMLFile.CLOSE; END; END ELSE BEGIN lPath := lCduCommonDialogManagement.OpenFile( 'Select a Import file', '', 4, LTXT_Filter, 0); IF lPath <> '' THEN BEGIN XMLFile.OPEN(lPath); XMLFile.CREATEINSTREAM(XMLStream); XMLPORT.IMPORT([YOUR IMPORT], XMLStream); XMLFile.CLOSE; END; END;0 -
Hi Ploeg,
Since I am exposing the codeunit as a web service, hope I cannot use UPLOAD function as it promts for a dialog box for selecting the file.
Instead I have tried using the below code:PushOrderDetails(VAR VarBigTxt : BigText) fileImport : Boolean lrecTempBlob.Blob.CREATEOUTSTREAM(OutStr); VarBigTxt.WRITE(OutStr); lrecTempBlob.Blob.CREATEINSTREAM(InStr); VarXML.SETSOURCE(InStr); IF VarXML.IMPORT THEN fileImport := TRUE ELSE ERROR('Import Unsuccessful');
The above code works fine when run locally but I am really stuck why the web service call cannot run the varxml.import function and it throws the exception "Import Unsuccessful". Really stuck ](*,) ](*,)
Going mad :xDilip
Falling down is not a defeat..defeat is when you refuse to get up.0 -
Try to call the import out of IF-Then to let NAV throw the original runtime error.0
-
Hi Kamil,
In that case, the web service throws the exception as shown in the attachment. I doesnt have any clue why is this happening when the same is working fine locally.
:-k :-k :-k :-k :-kDilip
Falling down is not a defeat..defeat is when you refuse to get up.0 -
THis exception means that you have confirm or dialog used in the code, but it means definitely, that the code is called at all... ;-)0
-
Thanks Kamil for the reply.
But the XMLPORT which I am using for IMPORT doesnt have any set of code. Any idea where the confirm or dialog possiblities would come while using IMPORT??Dilip
Falling down is not a defeat..defeat is when you refuse to get up.0 -
May be some OnValdiate or OnInsert is called in some table? How is the XMLPort called? It is as parameter of the function? Or through local variable?0
-
Is called through local variable.
Also for testing, I am trying to import only the primary key value of the table. And the table doesnt have any set of code in the OnIsert() and OnValidate() of the field which I am using in the XMLPORT.
Still the problem is same ](*,)Dilip
Falling down is not a defeat..defeat is when you refuse to get up.0 -
May be the XMLPort is asking for the file name? :-)0
-
I solved the same error several moths ago. Unfortunately I can't remember what reason was that. I'm not sure but I have feeling that temporary table (Temporary property) and something around this was the cause.0
-
I could finally analyse why the problem was.. And it was due to some OCX control function calls of LS Retail. I could able to handle the function calls and now the import function works like a gem through webservice.
But...
I have gone into the next problem now with the same web service. The next tast is to print the imported data from a windows printer. For that...
1. I have created a very simple report with just one data item
2. one control in the body section of that.
3. No code on the report.
4. Layout is created.
When I try to run the report, the same works fine locally, but again problem is when run using web service.
The system throws an exception saying "Callback Functions are not allowed"
Any clue where the user interface is obstructing with the following two line of simple code.IF ISSERVICETIER() THEN REPORT.RUNMODAL(50201,FALSE,FALSE,Record);
Awaiting on some ideas in breaking the same :-k :-k
Thanks all in advance.Dilip
Falling down is not a defeat..defeat is when you refuse to get up.0 -
I am not sure now, but I think that the problem is, that webservices cannot print... you can save the output into PDF and somehow send the pdf to the printer...0
-
Yes printing trough webservice is not possible. As Kine sais you need to generate a PDF and then print that. I discribed that in this topic:
http://www.mibuso.com/forum/viewtopic.php?f=32&t=46507&hilit=print+pdf
Please read last page carefully. I ended up writing a .net service that uses a FileSystemWatcher Class to watch a folder for incoming pdfs which had the printer name encoded in their filename to print the pdfs trough foxxit pdf reader (the external service is needed so you can run it under a domain user which you can assign printers to). I guess that's the best solution to do this!
Note: If you set up your NST to run under a domain account then you probably don't need the external service, you can do it with .net interop so foxxit reader would run under the context of a user that has printers assigned.0 -
I tried for the dll, but the website says the download doesnt exist. Pls. suggest where can I get the same.deV.ch wrote:Ok i found a solution that prints quick enough for my requirements:
-I generate the PDF with SAVEASPDF
-I use R2's DotNet Interop to use a DLL from Forensictools.net that can print PDF without the need of Acrobat Reader (But Printer must support PostScript)
The DLL is free! http://forensictools.net/
Also, as we are working on NAV 2009 SP1, kindly mention how the below function of your's should be changed as we dont have the dotnet datatype.StartProcess(_Filename : Text[250];_Arguments : Text[250]) Process := Process.Process(); ProcessInfo := ProcessInfo.ProcessStartInfo(_Filename,_Arguments); Process.StartInfo := ProcessInfo; Process.Start(); Process.WaitForExit(10000); // Wait max. 10 sec
Awaiting on your response deV.ch, Thank you in advance.Dilip
Falling down is not a defeat..defeat is when you refuse to get up.0 -
As i said i suggest to create a .net service that can watch a folder for incoming pdf files and prints these. This way you don't need .net interop (Nav 2009 R2) you simply save your report as pdf (SAVEASPDF) in the folder.
To save the file you can use this code:Printer := GetPrinterSelection(GetIDFromObjectID(ReportShipmentAvis.OBJECTID(FALSE))); FileName := GetFileName(Printer); SalesHead := _Record; SalesHead.SETVIEW(_RecView); ReportShipmentAvis.USEREQUESTFORM := FALSE; ReportShipmentAvis.SETTABLEVIEW(SalesHead); ReportShipmentAvis.SAVEASPDF(FileName);
GetPrinterSelection():UserSetup.GET(USERID); PrinterSelection.SETRANGE("Report ID", _ReportID); PrinterSelection.SETRANGE("User ID", USERID); IF PrinterSelection.FINDFIRST THEN EXIT(PrinterSelection."Printer Name");
GetFileName():Setup.GET; ServerUtil := ServerUtil.HttpUtility; _Printer := ServerUtil.UrlEncodeUnicode(_Printer); DateAndTime := FORMAT(TODAY,0,'<Month,2><Day,2><Year>') + '_' + FORMAT(TIME,0,'<Hours24>-<Minutes,2>-<Seconds,2>'); RandomPart := Path.GetRandomFileName(); FileString := '_%1_%2_Printer[%3].tmp'; FileName := Path.Combine(Setup."PDF File Path", STRSUBSTNO(FileString, COPYSTR(Path.GetFileNameWithoutExtension(RandomPart),1,50), DateAndTime, _Printer)); EXIT(FileName);
The GetFileName Function uses .net interop again, so you will need to rewrite it to get the same result. maybe File.CREATETEMPFILE or something like that to create a unique file name. The Printer Name is encoded since you can't use backslashes etc, in file names. I used .net interop here as well, but there is a Function UrlEncode in NAV Codeunit 801.
Thats all for the NAV Part.
Here is the a simplified version of my code in the service that prints the pdf files:public partial class Service1 : ServiceBase { [Conditional("DEBUG_SERVICE")] private static void DebugMode() { Debugger.Break(); } public Service1() { InitializeComponent(); this.ServiceName = "PDFPrintService"; } FileSystemWatcher watcher; protected override void OnStart(string[] args) { DebugMode(); watcher = new FileSystemWatcher(); watcher.Path = ConfigurationManager.AppSettings["PDF File Folder"]; watcher.Created += new FileSystemEventHandler(watcher_Event); watcher.Changed += new FileSystemEventHandler(watcher_Event); watcher.Renamed +=new RenamedEventHandler(watcher_Event); watcher.EnableRaisingEvents = true; EventLogHelper.WriteEventLog(String.Format("{0} started", Assembly.GetExecutingAssembly().FullName), EventLogEntryType.Information); } protected override void OnStop() { watcher.Dispose(); EventLogHelper.WriteEventLog(String.Format("{0} stoped", Assembly.GetExecutingAssembly().FullName), EventLogEntryType.Information); } void watcher_Event(object sender, FileSystemEventArgs e) { try { if (Path.GetExtension(e.FullPath).ToLower() == ".pdf") { if (ConfigurationManager.AppSettings["Debug"] == "true") EventLogHelper.WriteEventLog(string.Format("File Found \r\n\r\nFile: {0} ", e.Name), EventLogEntryType.Information); string Printer = ""; if (e.FullPath.Contains("Printer[")) { int start = e.FullPath.IndexOf("[") + 1; int end = e.FullPath.IndexOf("]"); Printer = e.FullPath.Substring(start, end - start); Printer = HttpUtility.UrlDecode(Printer).Trim(); } // Get Default Printer if Pritner String Emtpy if (Printer == String.Empty) { PrinterSettings settings = new PrinterSettings(); Printer = settings.PrinterName; } PrintPDFHelper.PrintPDF(ConfigurationManager.AppSettings["Foxit Path"], e.FullPath, Printer); } } catch (Exception ex) { EventLogHelper.WriteEventLog("Watcher Event Error ("+e.ChangeType.ToString()+ ") :" + ex.Message, EventLogEntryType.Error); } } }
And The Code for the PrintPDFHelper.PrintPDF Methodpublic static void PrintPDF(string PathPDFReader, string Filename, string Printer) { if(ConfigurationManager.AppSettings["Debug"] == "true") EventLogHelper.WriteEventLog(string.Format("Start Print \r\n\r\nReader:{0} \r\nFile: {1} \r\nPrinter {2}", PathPDFReader, Filename, Printer),EventLogEntryType.Information); string arguments = ""; if (Printer == "") arguments = string.Format("-p \"{0}\"", Filename); else arguments = string.Format("-t \"{0}\" \"{1}\"", Filename, Printer); ProcessStartInfo starter = new ProcessStartInfo(PathPDFReader, arguments); starter.UseShellExecute = false; Process process = new Process(); process.StartInfo = starter; try { int Timeout; if (!int.TryParse(ConfigurationManager.AppSettings["FoxitTimeout"], out Timeout)) Timeout = 10000; process.Start(); process.WaitForExit(Timeout); if (!process.HasExited) { process.Kill(); EventLogHelper.WriteEventLog(String.Format("Document '{0}' can't be printed: \r\nProbably Printer '{1}' not ready", Filename, Printer), EventLogEntryType.Warning); } } catch (Exception ex) { EventLogHelper.WriteEventLog("Foxxit Start Error: " + ex.Message, EventLogEntryType.Error); } finally { try { if (ConfigurationManager.AppSettings["DeleteFilesAfterPrint"] == "true") File.Delete(Filename); } catch (Exception ex) { EventLogHelper.WriteEventLog("File Delete Error: " + ex.Message, EventLogEntryType.Error); } } }0 -
Hi deV.ch,
Regrets if I am troubling you, I tried searching for creating a dotnet service but with no success. I have no knowledge on dotnet. Could you pls. mention the steps for the creating the dotnet service with the code u have mentioned as is below and how to use the same for NAV. I would be grateful to u..
Thanks in advance.deV.ch wrote:Here is the a simplified version of my code in the service that prints the pdf files:public partial class Service1 : ServiceBase { [Conditional("DEBUG_SERVICE")] private static void DebugMode() { Debugger.Break(); } public Service1() { InitializeComponent(); this.ServiceName = "PDFPrintService"; } FileSystemWatcher watcher; protected override void OnStart(string[] args) { DebugMode(); watcher = new FileSystemWatcher(); watcher.Path = ConfigurationManager.AppSettings["PDF File Folder"]; watcher.Created += new FileSystemEventHandler(watcher_Event); watcher.Changed += new FileSystemEventHandler(watcher_Event); watcher.Renamed +=new RenamedEventHandler(watcher_Event); watcher.EnableRaisingEvents = true; EventLogHelper.WriteEventLog(String.Format("{0} started", Assembly.GetExecutingAssembly().FullName), EventLogEntryType.Information); } protected override void OnStop() { watcher.Dispose(); EventLogHelper.WriteEventLog(String.Format("{0} stoped", Assembly.GetExecutingAssembly().FullName), EventLogEntryType.Information); } void watcher_Event(object sender, FileSystemEventArgs e) { try { if (Path.GetExtension(e.FullPath).ToLower() == ".pdf") { if (ConfigurationManager.AppSettings["Debug"] == "true") EventLogHelper.WriteEventLog(string.Format("File Found \r\n\r\nFile: {0} ", e.Name), EventLogEntryType.Information); string Printer = ""; if (e.FullPath.Contains("Printer[")) { int start = e.FullPath.IndexOf("[") + 1; int end = e.FullPath.IndexOf("]"); Printer = e.FullPath.Substring(start, end - start); Printer = HttpUtility.UrlDecode(Printer).Trim(); } // Get Default Printer if Pritner String Emtpy if (Printer == String.Empty) { PrinterSettings settings = new PrinterSettings(); Printer = settings.PrinterName; } PrintPDFHelper.PrintPDF(ConfigurationManager.AppSettings["Foxit Path"], e.FullPath, Printer); } } catch (Exception ex) { EventLogHelper.WriteEventLog("Watcher Event Error ("+e.ChangeType.ToString()+ ") :" + ex.Message, EventLogEntryType.Error); } } }And The Code for the PrintPDFHelper.PrintPDF Methodpublic static void PrintPDF(string PathPDFReader, string Filename, string Printer) { if(ConfigurationManager.AppSettings["Debug"] == "true") EventLogHelper.WriteEventLog(string.Format("Start Print \r\n\r\nReader:{0} \r\nFile: {1} \r\nPrinter {2}", PathPDFReader, Filename, Printer),EventLogEntryType.Information); string arguments = ""; if (Printer == "") arguments = string.Format("-p \"{0}\"", Filename); else arguments = string.Format("-t \"{0}\" \"{1}\"", Filename, Printer); ProcessStartInfo starter = new ProcessStartInfo(PathPDFReader, arguments); starter.UseShellExecute = false; Process process = new Process(); process.StartInfo = starter; try { int Timeout; if (!int.TryParse(ConfigurationManager.AppSettings["FoxitTimeout"], out Timeout)) Timeout = 10000; process.Start(); process.WaitForExit(Timeout); if (!process.HasExited) { process.Kill(); EventLogHelper.WriteEventLog(String.Format("Document '{0}' can't be printed: \r\nProbably Printer '{1}' not ready", Filename, Printer), EventLogEntryType.Warning); } } catch (Exception ex) { EventLogHelper.WriteEventLog("Foxxit Start Error: " + ex.Message, EventLogEntryType.Error); } finally { try { if (ConfigurationManager.AppSettings["DeleteFilesAfterPrint"] == "true") File.Delete(Filename); } catch (Exception ex) { EventLogHelper.WriteEventLog("File Delete Error: " + ex.Message, EventLogEntryType.Error); } } }Dilip
Falling down is not a defeat..defeat is when you refuse to get up.0 -
Here is a introduction to windows services: http://www.codeproject.com/Articles/14353/Creating-a-Basic-Windows-Service-in-C
I provided you my class Service1 which is equal to the class "WindowsService" in this tutorial. You can copy the code in the project you will create.
Since NAV is pushing in that direction i recommend you getting in touch with the whole .net world. but if you can't get it to work, i recommend you to conntact a .net developer to create this for you.
Unfortunatly right now i have no time to create a public version of my solution. Maybe i will do this in the near future. I see this could probably help some people, also i see that i should sum the whole topic up in a proper blog post. Since it involves lots of different parts, like permissions, domain users, windows services, pdf readers, etc...
Let me know if you managed to create the service, once you have this, its almost done.0
Categories
- All Categories
- 75 General
- 75 Announcements
- 66.7K Microsoft Dynamics NAV
- 18.8K 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
- 610 NAV Courses, Exams & Certification
- 1.9K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 251 Dynamics CRM
- 103 Dynamics GP
- 6 Dynamics SL
- 1.5K Other
- 991 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 28 Design Patterns (General & Best Practices)
- Architectural Patterns
- 9 Design Patterns
- 4 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1K General Chat
- 1.6K Website
- 77 Testing
- 1.2K Download section
- 23 How Tos section
- 249 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions
