I am having trouble working with a web service API which is using JSON data. I'm a long time C/AL programmer but I'm new to JSON type data and I'm not a .NET programmer so I'd like to achieve the goals of the project without having to write a new class. I have connected to the web service and can use the GET verb to retrieve data which comes in and apparently is deserialized by NAV since I can work with it immediately. The problem is that I need to use POST to create and update records in the API and i can't seem to get that to work. I'm not certain if I need to serialize the data being posted to the API or not. The API provider has very limited documentation.
Does anyone have an example of using standard .NET libraries to interact with a JSON web service from inside NAV? I learn really well from seeing examples. I have read all the posts on this forum that I could find on this forum and have learned much but i'm still coming up short.
Thanks!
Ron
:-)
Ron Taylor
ICS Support, Inc.
8541 154th Ave. NE
Redmond, WA. 98052
0
Comments
I'm facing the same challenge.
Tino Ruijs
Microsoft Dynamics NAV specialist
I'm still working on it but I have figured out several things. It turns out that I have not had to do any dotnet serialization work to get it all working to this point. I have used several ideas found in other Mibuso posts to get me started. There are a few dotnet objects needed but not the serialize or deserialize stuff. Although if you figure that part out it might help.
Here are my functions that are used in the code unit to call the webservice with various requests.
This small function is an example of calling the webservice function to get the json data and parse it into local data tables. The data is parsed and written to local data tables in the ParseResponseJson function. That function must be designed with sections for each different dataset you are expecting to receive. There are probably better ways to do this but with my limited knowledge of dotnet and desire to keep as much as possible inside the C/Side code this is what I was able to figure out.
UpdateUsersTable Function:
Local Variables: Response (Text) The CallWebService function has several dotnet variables:
StreamReader - DotNet - System.IO.StreamReader.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
StreamWriter - DotNet - System.IO.StreamWriter.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Request - DotNet - System.Net.HttpWebRequest.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
WebResponse - DotNet - System.Net.HttpWebResponse.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Credentials - DotNet - System.Net.NetworkCredential.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
And several text constants:
WebserviceRoot - https://portal.yourJsonSite.com/api/v1/
UserName - yourAPIusername
Password - yourAPIpassword
Host - yourHostSite.com
ContentType - application/json; charset=utf-8
The parameter RequestData would only be used with PUT or POST methods
The parameters parameter contains extra search parameters, etc.
I use this function primarily with the GET method. I had trouble getting the POST method to work correctly, this is one of the areas i'm still working on. I'm using the WinHTTP automation objects for the POST functions that I needed (see below). I'd like to figure out how to stream the web request using this function also. The variable ResponseData will have the text response from the web service that needs to be parsed.
This is an example of the response data I'm receiving. The code below is an example of my parsing code, all in C/Side. It strips all the unnecessary characters and grabs the object name from the data. It then splits the Json data into element pairs (FieldName,FieldValue) using SELECTSTR. Then saves the data into a local data file. in the code below there are two sections, one for the user object and one for the enrollments object.
Function ParseJsonResponse;
This function does the parsing and writing of the data into local tables. It could also be used to pass the data back to a calling function with the hash tables or a dimensioned variable I think. Note: The element name must match the case of the JSON data element name
Local Variables: x (Integer), l (Integer). p (Integer), ValuePair (Text), CurrentObject (Text), CurrentElement (Text), CurrentValue (Text), ElementName (Text), ElementValue (Text), NewString (Text), RecId (Integer), tmpDate (Date)
Text Constants: FormatChar - {}"'[] I also added a small function to convert the UTC datetime in the data stream to a Date variable to make things a little easier
This does not convert the datetime to local datetime. That is not needed in my implementation.
Local Variables: tmpDatetxt (Text)
An now for the real challenge, updating data on the Json server from the Employee file in NAV.
I have not been able to get the streaming to work with sending the data to the json server using the PUT verb with dotnet objects, so I have reverted to the automation "WinHTTPRequest" object to get this to work. The first function below will update the user account on the remote server with Employee information.
Local Variables:
WinHttpService - Automation 'Microsoft WinHTTP Services, version 5.1'.WinHttpRequest
RequestVar - Text
Local Text Constants:
UserJson - {'User': {'last_name' : '%1' , 'first_name' : '%2' , 'email' : '%3' , 'language' : '%4' , 'username' : '%5' , 'enabled' : '%6' }}
Parameter - /%1
WebserviceRoot - https://portal.yourJsonSite.com/api/v1/
UserName - yourAPIusername
Password - yourAPIpassword
Host - yourHostSite.com
ContentType - application/json; charset=utf-8 I'm not satisfied with this but it seems to work so far. If you come up with better solutions let me know!
:-)
ICS Support, Inc.
8541 154th Ave. NE
Redmond, WA. 98052
http://www.dynamics.is/?p=2303
JSON meets NAV
http://mibuso.com/blogs/davidmachanick/