Have you ever needed to connect to the Web services of one NAV instance from another one? If so, I bet that the approach was something like this: you created a .NET class where you defined a Web or Service reference to the target instance, and then you consumed that .NET class using .NET Framework interoperability. It was kind of clumsy, inflexible, but it worked.
How cool would it be if you could do something like this:
WITH WebService DO BEGIN
CONNECT(‘http://localhost:7047/DynamicsNAV70/WS/CRONUS%20International%20Ltd/Page/Customer’);
INIT;
SETVALUE(‘Name’,’Test Customer’);
SETVALUE(‘Blocked’,Cust.Blocked::Ship);
SETVALUE(‘Credit_Limit_LCY’,10000);
CREATE;
MESSAGE(‘I just created Customer No. %1 in another NAV instance.’,GETVALUE(‘No’));
END;
As a matter of fact, you can write something like that. You can write exactly that. And it compiles, runs, and accomplishes exactly what you expect it to do. The most beautiful thing, you don’t need to write a single line of code in Visual Studio, or deploy any external dependencies – it uses pure C/AL, and works equally well in NAV 2009 and NAV 2013.
The only thing you need is a simple codeunit that you can download from Mibuso. If you missed the link in the previous sentence, then click here.
I wrote that codeunit as a part of the demo I presented last Wednesday at Mibuso NAV TechDays 2012 in Antwerp, and as promised – I am making the code available for you to use.
This simple codeunit does no magic, it simply harnesses the power of the features built into the .NET Framework. It builds the proxy class and compiles it on the fly, and then uses reflection to instantiate objects, set properties, and call methods to allow you to interact with any NAV page web service.
Before you can consume a NAV page Web service from C/AL you do not need to know anything about the service, except for its URL. If it’s a page web service, you can use it to read, create, update, and delete data in another NAV instance, simply using C/AL.
At this stage, it supports the following page web service functions:
- Read
- ReadMultiple
- Create
- CreateMultiple
- Update
- UpdateMultiple
- Delete
Right now, I am providing no documentation for it, but I believe it should not be difficult to figure out what it can do by following these couple of examples.
Creating a customer
That’s the example above. Just declare a variable named WebService of type Codeunit 50113, and you are good to go.
Iterating through a set of customers read, with a filter applied
WITH WebService DO BEGIN
CONNECT(‘http://localhost:7047/DynamicsNAV70/WS/CRONUS%20International%20Ltd/Page/Customer’);
SETFILTER(‘Balance_LCY’,’>0′);
SETFILTER(‘Name’,’A*’);
IF READMULTIPLE THEN
REPEAT
MESSAGE(‘Customer %1 %2 has balance of %3’,GETVALUE(‘No’),GETVALUE(‘Name’),GETVALUE(‘Balance_LCY’));
UNTIL NEXT = 0;
END;
EXIT;
Updating an item
WITH WebService DO BEGIN
INIT;
SETVALUE(‘No’,’1000’);
READ;
SETVALUE(‘Description’,’Bicycle 2’);
UPDATE;
END;
Creating a purchase order from a sales order
WITH WebService DO BEGIN
CONNECT(‘http://localhost:7047/DynamicsNAV70/WS/CRONUS%20International%20Ltd/Page/PurchOrder’);
INIT;
SETVALUE(‘Buy_from_Vendor_No’,Rec."Sell-to Customer No.");
SalesLine.SETRANGE("Document Type",Rec."Document Type");
SalesLine.SETRANGE("Document No.",Rec."No.");
IF SalesLine.FINDSET THEN
REPEAT
NEWLINE;
SETLINEVALUE(‘Type’,FORMAT(SalesLine.Type));
SETLINEVALUE(‘No’,FORMAT(SalesLine."No."));
SETLINEVALUE(‘Quantity’,SalesLine.Quantity);
UNTIL SalesLine.NEXT = 0;
CREATE;
MESSAGE(‘Purchase Order No. %1 is created in the vendor”s system.’,GETVALUE(‘No’));
END;
I’ll be updating the functionality of this codeunit and uploading a more comprehensive version, as I find time to do this.
This post is a series of posts where I’ll present most of the stuff I talked about at NAV TechDays 2012, and expand those topics into the areas that I either had to leave out due to time constraints, or that I thought were not as interesting as those that I chose to put into the presentation.
Please, let me know how you like this small gadget.
Pingback: Web Services Black Belt: consuming NAV web services using pure C/AL - Navigate Into Success - NAV Non-Technical Blogs - Microsoft Dynamics Community
Pingback: Web Services Black Belt: consuming NAV web services using pure C/AL – 9/30, Navigate Into Success | Partner Compete
Where can we Get Codeunit 50113 and the source code of the Visual Studio project you’ve implemented during the NAV Tech Days.
@Tarek – I’ve uploaded it on Mibuso, and as soon as they approve the upload, I’ll link it from the blog post. You won’t miss it. Regarding the Visual Studio project, I’ll make a couple of blog posts around that, too, so stay tuned.
How to update Multiple Line Records, will it work using UPDATE function. Expecting quick reply .. thanks
Well, if you can do it with page web service proxy class in C#, you can do it here. I don’t think I specifically implemented support for assigning values to lines, but it shouldn’t be a difficult thing to do.
Hi Vjekoslav,
I have a compile error in the CU, The system canot find table “WebServicesSetup”? is this is a new table? should I create it ? or how can I solve this issue?
Thanks alot,
Zayed
You need to create this table. It contains credentials to connect, and from code you have it’s obvious what this table should look like. What it achieves is that it stores the credentials. Just figure your own way how to store and pass credentials to the web service and you are good to go.
You started obviously developing from c# to NAV? Doesn’t matter of course and your way of thinking is giving me new ideas how to look at NAV. Excellent.
Didn’t see a VS project. More ideas?
Erik: at first I did indeed develop this thing in C#, and then moved it to C/AL, but now it is pure C/AL and no C# at all. There is no VS project. Which VS project are you referring to?
Tarek is mentioning this “…and the source code of the Visual Studio project..”.
Would you mind sharing the C# version. I love this reflection. You don’t need to document it, just the functions is enough so I can start the debugger to understand it.
Hi,
Is this Codeunit the (fob and txt) only compatible with NAV2013.
As I cant import it into a NAV2009 R2 Database.
Pingback: Web Services Black Belt: consuming NAV web services using pure C/AL | Pardaan.com
Short bump.. and have the same problem with 2009. And why am i looking so sad?
Okay, okay, 🙂 I’ll catch some time to prepare a NAV2009 verified bersion and to post the C# version. Weekend looks likely.
Excellent.
I just imported the NAV 2009 code, but when I call it an error message “The DotNet variable has not been instantiated.” pops up. I traced it back to the line:
——
AssemblyReferences := AssemblyReferences.CreateInstance(DotNetType.GetType(‘System.String’),2);
——
Any suggestions how to fix this?
Fred: I don’t know, but I suspect it may be due to the hotfix that you are using. I’ve used the last one, and I did compile and test before releasing. For last hotfix for NAV 2009 R2, check Waldo’s blog at http://www.waldo.be/
Hi Fred
just want to confirm Vjekoslav solution.
Thanks Vjekoslav for the solution.
i had problems using it in NAV 2009 R2 (Build 32012).
With NAV 2009 R2 Build 33053 the example of Vjekoslav works fine.
Hi Fred,
Thanks for your great work, however, here is an error due to missing of the Table123456701 at the last function – Authenticate in the object.
Would you be so kind to release the table for us?
Thank you very much!
@Roy: Who’s Fred? My name is Vjeko, nice to meet you 🙂 I can’t check this thing about Table 123456701, but I am pretty sure it’s a rogue variable declaration, and that you can safely skip it, but I’ll do a check on my earliest.
Hi.
A table that is referencend and used in function Authenticate is missing. Variable name is WebServicesSetup and it refers to table 123456701. One could easily remove the variable and insert the values for user name and pwd hard coded, but just to let you know:
WITH WebServicesSetup DO BEGIN
IF GET THEN
ServiceInstance.Credentials := Credential.NetworkCredential(“User Name”,Password)
/Pauli
@Pauli: thanks for the comment. Yes – I am aware of that, but it can be easily figured out from the code what fields this table should contain. Or – you can do a quick fix that you did.
Hi Fred,
Another question is, is your solution compatible with https ?
i just try to use it for calling web service with SSL, but it failed.
Thanks!
Hi Vjeko,
I also tried to use this solution with SSL but it failed.
Do you know how to connect to web service with SSL?
Thanks in advance.
I’ve used this and it works very well for NAV 2009. Thanks for putting it together! It has some issues with NAV 2013 relating to the XML-consumption objects, though. Someday, maybe I’ll try and figure out how to do it in 2013 and do a write-up on it.
Strange, it should work better with 2013, because it provides better interoperability with .NET. I’ll really have to take a look and figure it out, but if you can also be more specific as to what doesn’t work well, it would help a lot.
Very nice work! I was blown away when you showed us at NavTechDays2012. The compile in memory could be used whenever a need for a new component is required.
“It helped” (requirements for your webservice CU hereby met :-)). Thank you for your great Work.
Regards
Gert Lynge
Thanks, Gert! Much appreciated! Good luck with it and leave some feedback in the future.
hi Vjeko,
excellent and ingenious tool, we are using it and it works fine on NAV 2009 & 2013.
Great!
Some questions please:
– would be possible in addition to the pages, you can also invoke codeunits published as Web Services?
for now, Iiput a function in the page that in the “Onload of the page” trigger, lanches the codeunit.
– it would be possible to extend the existing functionalities, inserting calls (Invokes) in codeunit and xmlports?
Thanks for support
Roberto
Roberto – it could be possible, yes. Codeunits for certain, XMLports would also be possible bu more complicated and less intuitive to work with from C/AL. I’ll see if I have time to continue working on this tool.
hi Vjeko, Do the CodeUnits functions for Webservice work from C/AL already available ?
“It helped” 🙂
It helped a lot in fact! Thank you for making this awesome tool available to all of us. I was just about to ask the same question as Roberto regarding codeunits, but I see that you have already answered that one. Hope you find time to extend the functionality.
Thanks again
Martin
Great stuff works like a charm. UseDefaultCredentials didn’t work for me while being on a local server. So i used:
//WITH WebServicesSetup DO BEGIN
// IF GET THEN
ServiceInstance.Credentials := Credential.NetworkCredential(‘john’,’1234′);
// ELSE
// ServiceInstance.UseDefaultCredentials := TRUE;
//END;
@vanAnaarB: You could have simply supplied username and password into the Web Service Setup table. But still, I am glad the code helped! Good luck with it!
hey i want to delete Sales Order and line from Navision 2013 using web services in C#.net,
how will i use delete according to my filter
plz tell me
Thanks in advance
@Karan: I don’t quite understand what exactly you want to achieve? If you want to delete Sales Order AND line – then it is enough to delete the Sales Order, and all its lines are deleted. If you want to delete a single line for a sales order, then you must call the Delete_SalesLines method on the web service. You must pass the Key parameter to it, and you can read the key from each of the lines in the Sales Order. You can find these in the SalesLines property of the sales order entity.
Hello,
I have a small problem with this code. I described it here
http://mibuso.com/forum/viewtopic.php?f=7&t=55040
But I need to run it on Windows Server 2012 R2. I checked this code on Windows Server 2008 and it works fine. The version of .NET Framework is the same. I’ve heard that in 2012 R2 handling of XML is changed. Maybe this is the cause of the problem?
Could you help me with this?
I would be very thankful.
Thanks in advance
@Damian: can you please let me know which page web service are you trying to access, when you get this parameter count mismatch error? It should have nothing to do with the handling of XML. Also, if you can provide the whole WSDL document of that page, as well as the page object exported as a text file, it would help. I suspect that this is a Worksheet page, or some other page where you have added some field controls above the topmost group control.
Thank you for the fast reply. I sent you everything in e-mail. If you could help me, it would be great.
@Damian: Well, just as I suspected – the metadata in the page is not correct. For web services to work correctly, you must put all the field controls into a Group control (a FastTab). If you just dump them into the ContentArea, then web services sees each of the fields as a parameter of all service methods for the web service, and my generic web service management code cannot work with that. So – to fix this, just add a Group just below the ContentArea and above the first Field, and then indent all the fields under the group, and it should magically work 🙂
It works, just perfect!!! 🙂 Thank you so much. It is not my page, so I didn’t notice that there is no grup inside. Thanks once again.
Hi,
I have another question. When I try to update one field, I get a message: “A DotNet variable has not been instantiated. Attempting to call System.Reflection.MethodInfo.GetParameters in CodeUnit Generic Web Service Client: UPDATE”. It occurs in this line: “Parameters := Parameters.CreateInstance(GETDOTNETTYPE(Object),_Create.GetParameters().Length);”. I use your code for updating. Do you know the solution?
Thanks for support.
Damian
Hello,
I would be thankful for your help.
Thank you
@Damian: I know, but I don’t have time to look deeper into this right now. Can you provide the page object for which this is failing? It again seems to me to be some kind of metadata problem on the page.
Ok, problem solved. Thanks. 🙂
All above information is helped me lot.. Created web service and integrated with JD Edwards 2I order system in my organization.
Hey!
Thank you for the help! It was a perfect start for my project. I need to use some extra functions besides CRUD that Pages provide.
If anybody needs to use Codeunit Web Services with the Page it is possible!
First create a Codeunit and publish as an extension of the Page (It has to be published with the same Name, and the functions included need a record parameter of the same type in Page).
Then few adjustments in Vjeko codeunit (defining the new methods) and voila!!
Thank you!
Hi,
had you finished to improve your tool for CodeUnit?
No, not yet, sorry. 🙁
Thanks Vjeko,
This is a great tool! It really helped! 😉
The only thing I’m missing is the possibility to use delegates (not your fault!) to be able to bypass certificate validate in our dev.env. Now we use a custom .NET Class for that.
Thanks,
Johannes
Thanks, Johannes! Unfortunately, yes – you need the custom .NET class for that.
Hi,
I have some problems when I use 2009 version.
– I can’t use SETVALUE function with fields that are not Text or Code. When I use the function with a boolean field, for example, I have this error: “The expresion type Microsoft.Dynamics.Nav.Runtime.NavIndirectValue can´t be converted to a value Microsoft.Dynamccs.Nav.Runtime.NavText.”
– I have a lot of errors like this “CustomerCard does not have a definition for the Territory_Code field”. Where can I find this definitions?
Thank you!!
David, can I see the code that causes the error when converting text to indirect value? I haven’t had any, I’ve even used it with the Option field. About the Territory Code field, do you actually have that field on the card, or is it just in the table?
Thank you for your answer!
This is my code:
CONNECT(‘192.168.2.125:7099/DynamicsNavXX/WS/XX/Page/CustomerCard’);
INIT;
SETVALUE(‘No’,Customer.”No.”);
SETVALUE(‘Name’,Customer.Name);
SETVALUE(‘Search_Name’,Customer.”Search Name”);
SETVALUE(‘Name_2’,Customer.”Name 2″);
//SETVALUE(‘Our_Account__No_’,Customer.”Our Account No.”);
//SETVALUE(‘Territory_Code’,Customer.”Territory Code”);
//SETVALUE(‘Collection_Method’,Customer.”Collection Method”);
//SETVALUE(‘Blocked’,Customer.Blocked);
CREATE;
The commented lines are the lines with error.
The customer card have this fields in the General group with Visible = FALSE.
Thanks
Strange, it works for me on NAV 2013, but I don’t have an instance of 2009 available anymore to test it there. Can you try if you experience the same problem with 2013 as well?
I found the problem. I call the codeunit from a report, and the Language of the report is not ‘ENU’.
Now It is running!
Thanks
Hi Vjeko
Great tool! I’m quite new to NAV and It helped a lot. Thank you.
My question: Is there really no way in the WebService Page to access the values passed with SETVALUE?
Best regards
Thanks, Dan! I am not sure, though, what you mean by this question. SETVALUE is used to set the values, not to access the values. Can you please clarify?
Hi Vjeko. Thanks for your answer. I try to clarify my problems
Within my webservice page, I attempt to access the values, that I have set with SETVALUE.
I have a simple Page that only writes the passed values as a new record into a table. In addition to the insert, i want to call a (cu) function using this values as parameters.
E.g.:
Type SubType SourceExpr
Container ContentArea
Group Group
Field “Triggered by Company Name”
Field “Company Name Called”
Field “Webservice Called”
Field “Parameter Type”
Field Parameter
OnInsertRecord(BelowxRec : Boolean) : Boolean
cuItemMgt.SyncItemSCfromWH(“Triggered by Company Name”,”Parameter Type”,Parameter);
The table insert works fine. No problem.
But, no matter what I try, the function (SyncItemSCfromWH) always receives blanks or nulls. Even if I call it at the table’s OnInsert Trigger.
Hello,
I’ve been working with Generic Web Service for a while, but never faced this problem.
I use Transfer Header Card.
The error shows up on Create method of the codeunit. System.Reflection.RuntimeMoethodInfo.Invoke : Thge max length for a string is 10.
I’m sending the transfer header no., and there should not be a problem with its length . In nav it is set to code 20…
Maybe something related to parameters?? any guess?
I answer myself… In transfer header insert trigger there’s was code regarding a “user” field which was 10 chaacter lenght.. fixed!
This was well over my head, but I wonder; Is there a way to make it work also for non-NAV webservices?
Håkan, yes – it is possible. I might do something like that in the future, but I can’t make any promisses. Principle is the same for all web services.
Thanks for the article Vjeko! Very interesting and useful! Have a nice time in Madrid!
Thanks for the article and code Vjeko – very valuable!
But it looks like there is a problem with the READ function if you try to do a READ on a page where there is an option value, as one of the key fields.
For test purpose I made a page with all fields from table 36 – Sales Header and tried this “code”:
WITH WebService DO BEGIN
CONNECT(‘http://…../Page/SH’);
INIT;
SETVALUE(‘Document_Type’, SH.”Document Type”::Order);
SETVALUE(‘No’,’1500005′);
READ;
And this gives me the error message:
A call to System.Reflection.RuntimeMethodInfo.Invoke failed with this message: Object of type ‘Document_Type’ cannot be converted to type ‘System.String’.
It would be appriciated is any had seen/solved this issue.
Thanks in advance.
I can’t play with this right now, but I assume you can try with:
SETVALUE(‘Document_Type’, FORMAT(SH.”Document Type”::Order));
I did try that before my initial post – gives same error result.
Hi. Any news on this isse that Kim Øvrum describes?
I’m using this tool a lot lately and there is a workaround for this.
Instead of using SETVALUE use SETFILTER, so in your example do it like this:
SETFILTER(‘Document_Type’, FORMAT(SH.”Document Type”::Order));
SETFILTER(‘No’,’1500005′);
Instead of using READ use READMULTIPLE but since you only need first record no need to REPEAT – UNTIL block so just add:
IF READMULTIPLE THEN BEGIN
END;
Hi Vjeko,
Have you upgraded this codeunit for calling XMLPorts/ codeunits etc, as you mentioned in your earlier post that you will do it in future?
Maybe someone else is made this code to work with codeunits ? and maybe could share it with us ?
Hi i had tried to call web service as you guide. i had used your code unit only. But while i am trying to call web service the line
RequestStream := WebRequest.GetResponse().GetResponseStream();
is giving me error – “a call to system.Net.HttpwebRequest.GetResponse failed with this message: the remote certificate is invalid according to the validation procedure.”
I have also passed NAVUserid and password as you suggested that code is –
ServiceInstance.Credentials := Credential.NetworkCredential(‘Admin’,’password’)
but still same.
can you please guide me for above issue.
Hi Vjeko,
I need this CodeUnit for the project that im working right now.
The site mibuso.com is down because they are working in their new web and its imposible to find this in other site.
Please, can you upload that CodeUnit in other place and share the link with us, for example in dropbox?
Thanks in advance.
You can grab it here: https://vjeko.com/long-time-no-see-vienna-nashville-demo-gods-and-other-things
Hi Vjeko,
I’m wondering the same as some of the other poster’s above:
Can this be used for web services with SSL?
I’ve tried but it’s failing for me also.
Thanks
SSL not working for me either.
Dear Vjeko,
Thank you for your greate tool.
We are inserting Sales Invoice from one nav database to another using web service.
The problem is we couldn’t figure out how to read from saleslines?
There is a GETLINEVALUE function, but not sure how to read repeatedly within salesinvoice multiread.
Could you please help on this issue?
Also i tried to create sales invoice updating thought Web Service exactly same way in above example code
“Creating a purchase order from a sales order”,
Unfortunately, not working, showing below error:
THE ERROR IS;
Microsoft Dynamics NAV
—————————
SalesInvoice does not have lines.
—————————
OK
—————————
If i debug the code, it is stoping in line below on CU Generic Web Service Client
AssertHasLines()
IF NOT HASLINES THEN
ERROR(Text006,Name);
Need to initiate SalesLine for WS SalesInvoice to SETLINEVALUE? How? Or should i missing something?
Please, give a guidance for my urgent issue..
Sorry, I haven’t tested it with sales lines.
Hi, Vjeko, residents and guests!
Please, tell me. Can I successfully work with this CU under Nav2009R2 Classic client (forms, reports, etc..)? Thank you for attention.
I am not quite sure of it. It was not developed for 2009 R2, and it may not work correctly. It’s a very very old version of NAV and I hope you understand why I can’t spend time trying to figure out if this would work under it.
How I can read all row from sales oder?
thanks a lot Vjeko for the codeunit, it works well in NAV 2015. Is there any new version which support calling OData webservice from another system or another NAV?
again, thank you very much.
No, sorry, I never extended it to support this. However, for OData you don’t need anything this complex, it can be as simple as using JSON.NET with HttpWebRequest.
Hi Vjeko,
in regards to your Example “Creating a purchase order from a sales order”
Is there is a way to Validate a field in the new Created Purchase order using your code?
This will be really helpful.
Best regards,
Mohamed
What do you mean by “validate”? All fields are always validated when making web service calls.
Hi Vjeko,
Your code is working Perfectly with the English Client! but If I use the German client it will now worl due to an error on this line:
Object := Enum.Parse(PropertyInfo.PropertyType,ValueText);
Do you have any idea how can I over come such issue?
Yes – use the English enum constant names. That’s the only way.
Thanks Vjeko for this brilliant piece of NAV-code. We used it to synchronize information between two independent systems and it is working really well (and the code for consuming web services is easy to understand). We’ve had a problem with the memory consumption on the service-tiers, because every CONNECT will compile a new assembly in memory and they will never be released again. So I mixed the function CONNECT with your state-service trick, essentially storing the assembly, the related URI and the WSDL in those static dictionary on the Service Tier and reuse it, when nothing has changed.
Thanks again.
Pingback: Thinking Enterprise Solutions
Hi Vjeko!
Can you please write a topic to guide how to create a web service to get list of invoices/vendors and pay invoices in NAV 2009 (using codeunit)?
Good one 🙂 Honestly?
Dear Vjeko,
I have an error when I tried tu use the CU to update a Purch.Invoice Header through web service.
This is my piece of code:
WITH WebService DO BEGIN
CONNECT(‘https://********/Page/FacturasPendientes’);
INIT;
SETVALUE(‘No’,”No.”);
READ;
SETVALUE(‘Approve’,FORMAT(“Approve”::Aprobado));
UPDATE;
END;
Is strange because the error is only throwed in the second SETVALUE statment, this is the message:
Microsoft Dynamics NAV
—————————
No se ha creado la instancia de la variable DotNet. Se está intentado llamar a System.Object.GetType en CodeUnit Generic Web Service Client: SetObjectValue
—————————
Aceptar
—————————
the translation is that the instance of the DotNet variable has not been created when the codeunit is trying to call the method SetObjectValue
Any idea about that?
Hm, I think it may have to do with the language. You are trying to assign the constant in Spanish, while .NET layer only sees English. Can you try to put “Approved” instead of “Aprobado”?
Pingback: Dynamics NAV Generic SOAP Client | NAV NAB BLOG
Hi my dear partner
you have some idea about how can i post purchase order? i need to do that from vb.net
thank you in advance.
You can’t do it using this example. This is only for page web services, not for codeunit web services. There are plenty of examples how to do what you need around the internet. Sorry that I don’t have much more time to delve into details now… 🙁
I’ve used this codeunit by an conversion/migration from NAV2009 to NAV20016. In NAV2009 i’ve publised the data as webservice.
Simple example of the code in NAV2016:
ConvertSalesPerson()
TimeVar[1] := TIME;
Window.OPEN(Text001);
WITH lWebService DO BEGIN
CONNECT(‘http://dev02:7047/DynamicsNAV/WS/CompanyName/Page/SalesPersonWS’);
Window.UPDATE(1,Salesperson.TABLECAPTION);
Salesperson.DELETEALL(TRUE);
SETFILTER(‘Job_Title’, ‘@inactief’);
SETFILTER(‘Name’, ‘*@NIET GEBRUIKEN*’);
IF READMULTIPLE THEN
REPEAT
CLEAR(Salesperson);
UpdateWindow(2,Salesperson.Code);
IF NOT Salesperson.GET(GETVALUE(‘Code’)) THEN BEGIN
Salesperson.Code := GETVALUE(‘Code’);
Salesperson.INSERT(TRUE);
END;
Salesperson.VALIDATE(Name, GETVALUE(‘Name’));
Salesperson.VALIDATE(“Job Title”, GETVALUE(‘Job_Title’));
Salesperson.MODIFY(TRUE);
UNTIL NEXT = 0;
END;
Window.CLOSE;
TimeVar[2] := TIME;
LogDuration(‘Salesperson’,TimeVar[1],TimeVar[2]);
It’s a nice and fast way to convert the data!
Thanks for sharing 🙂
Do you have any example code with GETLINEVALUE function
Thx!!!! This save me 🙂
You’re welcome! I am amazed that this is still pretty much alive out there 🙂
Hi Vjeko,
I try to use your codeunit to synchronize the item table of two company (on different server). But I get error with read-only field i.e. Last Date Modified. It is possible to know if a field is read only in Web Services, in this case for Item Card page?
I try to use an table for exclusion fields (read-only fields), but I get another error when I modify the unit price: the error say that: Field CalcUnitPriceExclVAT is readonly! But CalcUnitPriceExclVAT is a global function on the Item table … Why I get this error?
Because the page field you are trying to modify is apparently bound to a function. Rule is – if you can’t change it from UI, you can’t change it from Web Services.
It’s not possible directly. You’d have to somehow access page metadata (it’s an XML document in the Object Metadata table) and read it from there. And perhaps also do this for the underlying table. It’s not trivial.
Pingback: Dynamics NAV Generic SOAP Client - Microsoft Dynamics NAV Community
Pingback: Posting with Limited Users? - Microsoft Dynamics NAV Community
Pingback: Posting with Limited Users? - Roberto Stefanetti's NAV Blog - Dynamics NAV Users - DUG
Pingback: Posting with Limited Users ? NO. - Microsoft Dynamics NAV Community
I have a problem with date fields? When I get the date from the GETVALUE function, the date is in the dutch format instead of english format. AND it is the date minus one day. How does this happen?
I have the same problem with dates as well. I need to send data from one DB in one language, to another DB (on another server) with different language and timezone. Maybe something to do with that?
In any case, I ended up splitting the date into 3 integers, and combining them to the correct date later.
I changed the field to text and filled it with the Format(,9) option so it becomes a xml date value.
Sorry, I don’t know this (anymore). There must be ways to do this, but I am not actively maintaining this codeunit anymore, so I can’t help you directly.
Vjeko Fantastic! With a little work I have managed to complete support for SubPages. I had to change ‘Lines’ from Array to Collection and assign object to Entity.Lines when move through records with Entitys.NEXT. Also added a function LINES_NEXT to move though collection of Lines.
Works great! Good to see you at NAV Tech Days 2017! Keep up the good work! Thank you!
You’re welcome! I am always happy to hear that my work is useful to others.
Can you send your code? Maybe Vjeko can update the post?
Great Example – Thanks
Pingback: My Soap Service Proxy Codeunit – Gunnar's Blog
Pingback: My Soap Service Proxy Codeunit - Gunnar's Blog - Business Central/NAV User Group - DUG
Sometimes I have an error when I tried tu use the CU to update a custom table through web service.
This is my piece of code:
WITH WebService DO BEGIN
CONNECT(**********************************************’);
INIT;
SETVALUE(‘Id’,VoucherD.Id);
READ;
SETVALUE(‘UsedQuantity’,VoucherD.UsedQuantity);
UPDATE;
END;
And this is the error:
Calling to System.Reflection.RuntimeMethodInfo.Invoke failed with this message: Other user has modified “Voucher_Line_detail” “Id=CONST(6575)”
Thanks
Well, I can imagine people are getting errors with this, but this was written for NAV 2009 R2, and I never really updated it for anything newer. I can’t provide any active support for this, sorry 🙁
Hello Sir,
i am getting this error
CustmerList does not have a definition for the field.
Yes, very likely. This is mostly proof of concept and not a finalized solution. Also, it was intended to be used on NAV 2009 R2, and was never updated for any future releases – I would be surprised if it just worked without any changes.
Hi. I hope if some of you subscribes to this can answer. This has worked like a charm for over a year now, But now I get “A call to System.Net.HttpWebRequest.GetResponse failed with this message: An existing connection was forcibly closed by the remote host”
This only happens if there are a sizeable (well, not very much) amount of data involved.
A google search reveals that one copuld try to set keepAlive := false, but i ‘cant see a class that have this property.
Any pointers would be helpful.
Thanks.
Pingback: My Soap Service Proxy Codeunit - Gunnar's Blog - Dynamics 365 Business Central/NAV User Group - Dynamics User Group
This is a great post that helps me a lot! i am using this to handle some intercompany stuff. However, has anyone made it work for codeunit? I use the Web Service extension method where i create a codeunit webservice entry with the same name as the Page Web Service and just not publish it. in the WSDL of the page WS, i do see the DoSomething function from the codeunit in the WSDL, but i failed to make it work, i am getting some .Net Runtime error when i called the DoSomething function.
“A call to System.Reflection.RuntimeMethodInfo.Invoke failed with this message: Object of Type XXX cannot be converted to System.String’
I made a copy of the UPDATE function , perhaps it is something in here that i did wrong….any ideas?
DoSomething()
AssertAllowed(DOSOMETHINGALLOWED);
AssertInitialized;
Parameters := Parameters.CreateInstance(GETDOTNETTYPE(Object),_Create.GetParameters().Length);
Parameters.SetValue(Entity,Parameters.Length – 1);
Service := Activator.CreateInstance(ServiceType);
Authenticate(Service);
_doSomething.Invoke(Service,Parameters);
Entity := Parameters.GetValue(Parameters.Length – 1);
I’m facing this error when trying to update Nav with a payload from webservice. How can i fix this:
SOAP ERROR: /var/www/Company/production/Company_ws/chr/components/AssetVerificationUpdate.inc.php on line 159. REASON: Other user has modified “OTI_Asset_Varification” “No.=CONST(XXXXXX)”
You can’t. If another user has modified a record in between you reading and writing, this is what you get. It’s called concurrency. You’d need to catch this specific error, and if it occurrs, do the re-read, and then attempt re-write.
Hi Vjeko,
nice post, i applied your codeunit in my testing db, but unfortunately the system will show the error if the company name with comma inside.
here below the error :
Microsoft Dynamics NAV
A call to System.Reflection.RuntimeMethodInfo.Invoke failed with this message: Service “Tester%2C Company/Page/Customer_List_Tester” was not found!
OK
and the system pointing to that codeunit function CREATE :
_Create.Invoke(Service,Parameters);
can you help me how to configure it? thanks.
Sorry, I can’t do much to help you with this. Change the name of the test company if the comma in the name is the problem.
Hi Vjeko,
This is some great stuff thanks for this!
Hope someone tried this with codeunit instead of page.
Thank you & God bless!
Great post (as always)… I’m just curious. What search terms did you use to discover those (creative commons licensed) photos? That first one is so so perfect for this topic.
Seriously, you are asking me about what search terms I used to discover a photo I put there ten years ago? Honestly, I don’t remember.
However, the “(creative commons licensed)” part of your comment sounds a bit sarcastic to me, so what is it really that you are asking me about?
Hi Vjeko,
I am facing below error, A call to System.Net.HttpWebRequest.GetResponse failed with this message: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
Thanks,
johnson
Sorry, don’t know what’s causing this. Firewall, network configuration, something of the sort. It’s not my code, and it’s not BC/NAV, at least that’s obvious from your description of the problem.
Thank you very very much Vjeko. It works fine with BC14, the last C/AL edition.
I only have one problem making READ with Option fields in primary key of the table. But there are several ways to do the same things. 🙂
You’re welcome, and I am glad this (very, very) old piece of code I did still helps people. I imagine a lot will not work anymore, because 10+ years have passed. Thanks for the comment 😊
Hello,
Here is my code:
1 WITH WebService DO BEGIN
2 CONNECT(‘http://10.150.1.109:7057/ENTW/WS/K-Solutions GmbH/Page/ServiceContractHeader’);
3 //Service Contract header
4 INIT;
5 SETVALUE(‘Contract_Type’,1);
6 SETVALUE(‘Customer_No’, ‘123’);
7 SETVALUE(‘Description’, ‘TestContract’);
8 //Sevice ContractLine
9 NEWLINE;
10 SETLINEVALUE(‘Description’, ‘TestContractLine’);
11 CREATE;
12 END;
If I comment the lines 9 and 10, a service contract header is created. Howver, with the whole code I get this error (in CREATE level):
This message is intended for C/AL programmers: Error when calling ‘System.Reflection.RuntimeMethodInfo.Invoke’: ‘Description’ must contain a value in ‘Service Contract Line’: ‘ContractType=Contract, ContractNo.=123, LineNo.=10000’. The value must not be zero or empty.
Why do I get this error even though I set the value of Description field in SETLINEVALUE(‘Description’, ‘TestContractLine’); ?
I don’t honestly know. I’d suggest you try debugging on your end to see what’s causing this behavior.