Navision 2009 SP1 Web Services / RTC issues
Robert_Ellsworth
Member Posts: 19
Hello everyone,
I'm trying to setup a 3-tier installation following the Walkthough provided by Microsoft: ( https://msdn.microsoft.com/en-us/library/dd301254.aspx )
I have 2 machines currently setup. First is the SQL Server (omisqldev), and the second machine is the Web Services machine (ws1). Both machines are members of the EOMEGA domain, and I created 1 Domain User for use for both system's services (SQLAdmin).
Here are the services for the Web Services server:

Here are the services for the SQL Server:

Here is the Domain User for both services:

Here is the list of delegations, reported by setspn:

And this is the output of the Best Practices Analyser:

Unless I'm missing something, the MSSQLSvc/omisqldev.eomega.org SPN is defined for the service account user. I don't know what's missing in the setup.
When I try to connect from a third machine via Web Services, I am presented with a login screen:

After providing the credentials for a local account to WS1 (Domain Users didn't work) I get:

Anyone have any suggestions on where I should go next or what the missing piece to this puzzle is?
Thanks for taking the time to read this,
- Rob
I'm trying to setup a 3-tier installation following the Walkthough provided by Microsoft: ( https://msdn.microsoft.com/en-us/library/dd301254.aspx )
I have 2 machines currently setup. First is the SQL Server (omisqldev), and the second machine is the Web Services machine (ws1). Both machines are members of the EOMEGA domain, and I created 1 Domain User for use for both system's services (SQLAdmin).
Here are the services for the Web Services server:

Here are the services for the SQL Server:

Here is the Domain User for both services:

Here is the list of delegations, reported by setspn:

And this is the output of the Best Practices Analyser:

Unless I'm missing something, the MSSQLSvc/omisqldev.eomega.org SPN is defined for the service account user. I don't know what's missing in the setup.
When I try to connect from a third machine via Web Services, I am presented with a login screen:

After providing the credentials for a local account to WS1 (Domain Users didn't work) I get:

Anyone have any suggestions on where I should go next or what the missing piece to this puzzle is?
Thanks for taking the time to read this,
- Rob
0
Comments
-
Hi,
Do you set "WebServicesUseNTLMAuthentication = true" under service config?
Regards,
YukonMake Simple & Easy0 -
Yes, I have tried it with WebServicesUseNTLMAuthentication = true, and false. Neither setting made a difference
0 -
Hi,
How about the RTC? Can you open the nav with RTC? What is the database role membership for SQLAdmin on your database. If you still face with same error, try to use separate a/c and re-configure again.
Regards,
YukonMake Simple & Easy0 -
Hello,
The Windows users have been added to the database. I can connect using the Classic client in Windows Authentication mode for the SQLAdmin user.
Also, I am able to run the RTC, but only on WS1 (when logged into the domain with SQLAdmin).
It looks to be a delegation issue, as the SQL Logs show attempts of logging in as Anonoymous
Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'. Reason: Token-based server access validation failed with an infrastructure error. Check for previous errors. [CLIENT: 192.168.0.51]
The infrastructure error is the missing SPN that IS setup (at least what I believe to be setup, as provided by the setspn screen capture I provided). The BPA says the SPN isn't setup, when it looks like it is.
Thank you for your answers so far Yukon,
- Rob0 -
It was the "WebServicesUseNTLMAuthentication" change to true afterall.
I figured out where my error was in this whole process.
After I had set (on the Navision Service) the "WebServicesUseNTLMAuthentication" to true, I never tested logging into Web Services with the Domain User. I was able to log in to Web Services with the Domain User and I got the expected results from the session:This XML file does not appear to have any style information associated with it. The document tree is shown below. <discovery xmlns="schemas.xmlsoap.org/.../" xmlns:xsi="www.w3.org/.../XMLSchema-instance" xmlns:xsd="www.w3.org/.../XMLSchema"> <contractRef xmlns="schemas.xmlsoap.org/.../" ref="192.168.0.51/.../Omega Testing 2014/SystemService"/> <contractRef xmlns="schemas.xmlsoap.org/.../" ref="192.168.0.51/.../Omega Testing 2014/Page/Contact"/> <contractRef xmlns="schemas.xmlsoap.org/.../" ref="192.168.0.51/.../Omega Testing 2014/Page/Customer"/> <contractRef xmlns="schemas.xmlsoap.org/.../" ref="192.168.0.51/.../Omega Testing 2014/Page/RoomCategory"/> </discovery>
Thank you for your assistance Yukon!0 -
Hello everyone, I'm now at a point where I am trying to access a codeunit from PHP. I have the codeunit registered with WS, and I can pull up the WDSL for it:
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:microsoft-dynamics-schemas/codeunit/GuestInfo" targetNamespace="urn:microsoft-dynamics-schemas/codeunit/GuestInfo"> <types> <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="urn:microsoft-dynamics-nav/xmlports/GetGI" elementFormDefault="qualified" targetNamespace="urn:microsoft-dynamics-nav/xmlports/GetGI"> <complexType name="ContactHeader"> <sequence> <element minOccurs="1" maxOccurs="unbounded" name="ContNoTitle" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContNameTitle" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContName2Title" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContAddressTitle" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContAddress2Title" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContAddress3Title" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContCountyTitle" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContPostCodeTitle" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContCityTitle" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContCountryRegionCodeTitle" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContE-MailTitle" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContFirstNameTitle" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContMiddleNameTitle" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContSurnameTitle" type="string"/> <element minOccurs="1" maxOccurs="unbounded" name="ContE-ActiveTitle" type="string"/> </sequence> </complexType> <complexType name="Contact"> <sequence> <element minOccurs="1" maxOccurs="1" name="No" type="string"/> <element minOccurs="1" maxOccurs="1" name="Name" type="string"/> <element minOccurs="1" maxOccurs="1" name="Name2" type="string"/> <element minOccurs="1" maxOccurs="1" name="Address" type="string"/> <element minOccurs="1" maxOccurs="1" name="Address2" type="string"/> <element minOccurs="1" maxOccurs="1" name="Address3" type="string"/> <element minOccurs="1" maxOccurs="1" name="County" type="string"/> <element minOccurs="1" maxOccurs="1" name="PostCode" type="string"/> <element minOccurs="1" maxOccurs="1" name="City" type="string"/> <element minOccurs="1" maxOccurs="1" name="CountryRegionCode" type="string"/> <element minOccurs="1" maxOccurs="1" name="EMail" type="string"/> <element minOccurs="1" maxOccurs="1" name="FirstName" type="string"/> <element minOccurs="1" maxOccurs="1" name="MiddleName" type="string"/> <element minOccurs="1" maxOccurs="1" name="SurName" type="string"/> <element minOccurs="1" maxOccurs="1" name="EActive" type="string"/> </sequence> </complexType> <complexType name="Root" mixed="true"> <sequence> <element minOccurs="1" maxOccurs="unbounded" name="ContactHeader" type="tns:ContactHeader"/> <element minOccurs="1" maxOccurs="unbounded" name="Contact" type="tns:Contact"/> </sequence> </complexType> <element name="Root" type="tns:Root"/> </schema> <schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:microsoft-dynamics-schemas/codeunit/GuestInfo"> <element name="GetGuest"> <complexType> <sequence> <element minOccurs="1" maxOccurs="1" name="guestNo" type="string"/> <element xmlns:q1="urn:microsoft-dynamics-nav/xmlports/GetGI" minOccurs="1" maxOccurs="1" name="gIXML" type="q1:Root"/> </sequence> </complexType> </element> <element name="GetGuest_Result"> <complexType> <sequence> <element minOccurs="1" maxOccurs="1" name="return_value" type="int"/> <element xmlns:q2="urn:microsoft-dynamics-nav/xmlports/GetGI" minOccurs="1" maxOccurs="1" name="gIXML" type="q2:Root"/> </sequence> </complexType> </element> </schema> </types> <message name="GetGuest"> <part name="parameters" element="tns:GetGuest"/> </message> <message name="GetGuest_Result"> <part name="parameters" element="tns:GetGuest_Result"/> </message> <portType name="GuestInfo_Port"> <operation name="GetGuest"> <input name="GetGuest" message="tns:GetGuest"/> <output name="GetGuest_Result" message="tns:GetGuest_Result"/> </operation> </portType> <binding name="GuestInfo_Binding" type="tns:GuestInfo_Port"> <binding xmlns="http://schemas.xmlsoap.org/wsdl/soap/" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="GetGuest"> <operation xmlns="http://schemas.xmlsoap.org/wsdl/soap/" soapAction="urn:microsoft-dynamics-schemas/codeunit/GuestInfo:GetGuest" style="document"/> <input name="GetGuest"> <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="literal"/> </input> <output name="GetGuest_Result"> <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="literal"/> </output> </operation> </binding> <service name="GuestInfo"> <port name="GuestInfo_Port" binding="tns:GuestInfo_Binding"> <address xmlns="http://schemas.xmlsoap.org/wsdl/soap/" location="http://192.168.0.51:7047/DynamicsNAV/ws/Omega%20Testing%202014/Codeunit/GuestInfo"/> </port> </service> </definitions>
The function in the codeunit is called GetGuest and it has 2 parameters. First is the GuestNo, which is the value linked to a Contact Record, and the second parameter is GIXML, which is an VAR declared XMLPort to the Contact table. I am trying to access this codeunit via PHP, and am having no luck in getting the XML back from the function.
Using both Freddy.DK's blogs, as well as Arte's blog post regarding NAV and PHP, I am able to do the basics like accessing the Company List and reading information via a page. When I try to access the codeunit though, I am getting a SOAP Exception: ERROR: SoapException: [SoapFault exception: [a:System.Xml.XmlException] Data at the root level is invalid. Line 1, position 1. in /opt/lampp/htdocs/guest.php:18
Here's the code in my guest.php file:<? include('nav_soap_client.php'); stream_wrapper_unregister('http'); // we register the new HTTP wrapper stream_wrapper_register('http', 'NTLMStream') or die("Failed to register protocol"); // Initialize Soap Client $baseURL = 'http://192.168.0.51:7047/DynamicsNAV/ws/Omega Testing 2014/'; $client = new NTLMSoapClient($baseURL.'Codeunit/GuestInfo'); $params = array(); $params["guestNo"] = "CT0061822"; $params["gIXML"] = null; stream_wrapper_restore('http'); try { $result = $client->GetGuest($params); if ($result->return_value == 1) { $ret = TRUE; } } catch(Exception $e){ // here should be some nice debugging if you want echo "<hr><b>F`in ERROR: SoapException:</b> [".$e."]<hr>"; echo "<pre>".htmlentities(print_r($client->__getLastRequest(),1))."</pre>"; } $xmldata = $result->gIXML; $contno = $xmldata->No; $fname = $xmldata->FirstName; $mname = $result->MiddleName; $lnane = $result->Surname; $email = $result->Email; $emactive = $result->EActive; echo "Contact No.:".$contno." Name:".$fname." ".$mname." ".$lname; ?>
Basically, I'm not getting anything back from the codeunit. The XMLPort does work, as I have written a test codeunit to generate an XML file with it.
Here's what my registered codeunit looks like:OBJECT Codeunit 50090 Test Guest Info { OBJECT-PROPERTIES { Date=08/14/15; Time=12:09:16 PM; Modified=Yes; Version List=; } PROPERTIES { OnRun=BEGIN END; } CODE { PROCEDURE GetGuest@1000000000(GuestNo@1000000000 : Code[20];VAR GIXML@1000000003 : XMLport 50000) : Integer; VAR Cont@1000000001 : Record 5050; GIX@1000000002 : XMLport 50000; BEGIN IF NOT Cont.GET(GuestNo) THEN EXIT(-1); Cont.SETRANGE("No.", GuestNo); GIXML.SETTABLEVIEW(Cont); END; BEGIN END. } }
Any assistance here would be greatly appreciated.
Thanks for taking the time to read this.0 -
Hi Robert,
First, if you have error checks in functions that are called using webservices, you should not use the exit, but an error instead.
It appears that the XMLPort is called anyway, no matter if you Exit the function. You can only prevent this from happening with an error.
Second, the error message you get "Data at the root level is invalid" tells something about the XML returned through the XMLPort. Did you check all properties of your XMLPort?
for example:
Encoding : UTF-8
XMLVersionNo : 1.1
Format/Evaluate : XML Format/Evaluate
regards, Remco0 -
Remco Reinking wrote:Hi Robert,
First, if you have error checks in functions that are called using webservices, you should not use the exit, but an error instead.
It appears that the XMLPort is called anyway, no matter if you Exit the function. You can only prevent this from happening with an error.
Second, the error message you get "Data at the root level is invalid" tells something about the XML returned through the XMLPort. Did you check all properties of your XMLPort?
for example:
Encoding : UTF-8
XMLVersionNo : 1.1
Format/Evaluate : XML Format/Evaluate
regards, Remco
Hello Remco,
Thanks for the heads-up on Exiting a function when XMLPorts are involved. Makes sense. I will change those to error calls instead of exits.
I have tried all of those settings for the XMLPort (The Format/Evaluate, version, etc.) and the PHP code still doesn't work.
What the function is supposed to do is return data via the XMLPort. Even though I have the XMLPort setup as Export-Only, I fear the codeunit is trying to execute it as an Import (Since I am feeding the function a null object, and not explicitly calling the XMLPort with XMLPort.EXPORT().
I can get the data out as a Page, but the pages are behaving differently than the XMLPort. When I extract the data via a page, if a field has no value in the table being accessed it is omitted from the output from the page entirely. In the PHP code I have to test for the existence of the element via isset() for every field which is annoying.
Ideally I'd like the codeunit to work but I'm not having any luck.
Thank you for the suggestions though. Appreciate the help
- Rob0 -
Hi Rob,
It should be no problem to call the EXPORT in the function. And you can use it to check if it succeeded:
e.g. this is a function that also gets called through a webservice using php :PROCEDURE GetCustomerDetails(LoginID : Integer;SellToCustomerNo : Code[20];VAR CustomerDetails : XMLport "Customer Details") Result : Text[100] IF NOT CheckLoginID( LoginID, 'GetCustomerDetails') THEN ERROR('ERROR:Invalid loginID'); Result := CheckCustomer( SellToCustomerNo, Customer); IF Result = 'OK' THEN BEGIN Customer.SETRECFILTER; CustomerDetails.SETTABLEVIEW( Customer); IF NOT CustomerDetails.EXPORT THEN BEGIN Result := 'ERROR:'+COPYSTR(GETLASTERRORTEXT,1,93); ERROR( Result) END; END ELSE ERROR(Result);
Just another question: Is the first node in your XMLPort a text element?
Remco0 -
Here's the codeunit now. I took out the need for using EXIT and if something does go wrong I throw errors:
GetGuest(GuestNo : Code[20];VAR GIXML : XMLport "Guest XML") IF NOT Cont.GET(GuestNo) THEN ERROR('-1'); Cont.RESET; Cont.SETRANGE("No.", GuestNo); GIXML.SETTABLEVIEW(Cont); IF NOT GIXML.EXPORT THEN ERROR('ERROR:'+COPYSTR(GETLASTERRORTEXT,1,93));
The first node in my XMLPort is a Text Field (Root);
I added in code to manually do the EXPORT, and it seems to complete but is still not returning anything to the php object. I have written a test codeunit to see if I can generate an xml file using the XMLPort, and it works so I'm a tad confused as to what's wrong.0
Categories
- All Categories
- 73 General
- 73 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
- 617 NAV Courses, Exams & Certification
- 2K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 328 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