JSON in 1C:Enterprise 8.3.6

Publications: JSON in 1C:Enterprise 8.3.6JSON (JavaScript Object Notation) is a text format of data exchange which is widely used in the web-applications. Compared with XML, it is more compact and occupies less space. In addition, all the browsers have the built-in tools to work with JSON.
The necessity to work with this format at the platform level is caused not only by the fact that this is a «fashionable modern» format which the application solutions of 1С:Enterprise can use by themselves for integration with third-party applications. Another reason is that JSON is widely used in the HTTP interfaces. And 1С:Enterprise just has such mechanisms in which you want to use this format. These are the application REST interface automatically generated by the platform and the HTTP-services which you can create by yourself.

We see several basic scenarios to use JSON.

Firstly, this is an integration with external systems using their HTTP interfaces: Google Calendar, Salesforce.com, REST interface of 1С:Enterprise, SharePoint, etc.
Secondly, this is an organization of your own HTTP interface for application solution.
Thirdly, exchange of JSON files with external systems. Generation of configuration, setup files. Their use in the data exchange procedures, for example, with online-shops.
Fourthly, this is the use of JSON files for data exchange with different 1С:Enterprise applications.
We have implemented in the platform several layers to work with JSON. The most simple and flexible are the low-level tools for data-flow read and write. More high-level and not so universal are the tools to serialize in JSON the primitive types and collections of 1С:Enterprise.

Data-flow JSON read and write

The objects of data-flow operation are the common objects JSONReader and JSONWriter. They read JSON successively from file or string or write JSON successively in file of string. Thus, JSON read and write are performed without generating the entire document in memory.

As an illustration of data-flow JSON read we can give the following example:

	// Example of JSON reading.
	JSONReader = New JSONReader;
	// Open file or set up a JSON string.
	JSONReader.OpenFile("FileName");
	//JSONReader.SetString("JSONString");
	While JSONReader.Read() Do
		JSONType = JSONReader.CurrentValueType;
		If JSONType = JSONValueType.Number OR JSONType = JSONValueType.String
			OR JSONType = JSONValueType.Boolean OR JSONType = JSONValueType.Null Then
			// process value
			Value = JSONReader.CurrentValue;
		ElsIf JSONType = JSONValueType.Comment Then
			// process Comment
			Comment = JSONReader.CurrentValue;
		ElsIf JSONType = JSONValueType.PropertyName Then
			// process property name
			PropertyName = JSONReader.CurrentValue;
			
		ElsIf JSONType = JSONValueType.ArrayStart OR JSONType = JSONValueType.ArrayEnd
			OR JSONType = JSONValueType.ObjectStart OR JSONType = JSONValueType.ObjectEnd 
			OR JSONType = JSONValueType.None Then 
			
			//process objectarray startend or nothing
			//CurrentValue is not accessible
			
		EndIf;
	EndDo;
	
	JSONReader.Close();

When writing JSON, you generate yourself its structure. To «insure» you from mistakes, the object JSONWriter automatically checks the validity of the written structure. To increase the speed of operation, this check can be disabled. In the example below this is a string:
JSONWriter.ValidateStructure = False;

Also, on writing, you can control some parameters of generated text, for example, using the double quotes, line breaks, indent characters and quoting. In the example below the tab is used for text formatting:

JSONWriterSettings = new JSONWriterSettings(, Chars.Tab);
JSONWriter.OpenFile("FileName",,, JSONWriterSettings);

The data-flow JSON write may look as follows. An array of four items is written. Three of them are with primitive type and the fourth item is an object with two properties:

 
	// Example of JSON writing.
	JSONWriter = New JSONWriter;
	//To increase the speed of operation, this check will be disabled
	JSONWriter.ValidateStructure = False;
	//Use TAB for format output text
	JSONWriterSettings = new JSONWriterSettings(, Chars.Tab);
	//open file or set upo writing into string
	JSONWriter.OpenFile("FileName",,, JSONWriterSettings);
	//JSONWriter.SetString(JSONWriterSettings);
	
	//Write array
	JSONWriter.WriteStartObject();
		JSONWriter.WritePropertyName("PropertyArray");
		JSONWriter.WriteStartArray();
			//string
			JSONWriter.WriteValue("String example");
			//number
			JSONWriter.WriteValue(12.222, True);
			//boolean
			JSONWriter.WriteValue(True);
			//object
			JSONWriter.WriteStartObject();
				JSONWriter.WritePropertyName("Field1_String");
				JSONWriter.WriteValue("String example for object");
				JSONWriter.WritePropertyName("Field1_None");
				JSONWriter.WriteValue(Undefined);
			JSONWriter.WriteEndObject();
		JSONWriter.WriteEndArray();
	JSONWriter.WriteEndObject();
	
	JSONWriter.Close();
	//JSONString = JSONWriter.Close();

A result of such writing:

{
	"PropertyArray": [
		"String example",
		1.2222E1,
		true,
		{
			"Field1_String": "String example for object",
			"Field1_None": null
		}
	]
}

Serialization of primitive types and collections in JSON

The second group of tools to work with JSON is good because it frees you from the chore of reading/writing each individual value or property. On reading, the JSON documents are reflected to a fixed set of platform types: String, Number, Boolean, Undefined, Array, FixedArray, Structure, FixedStructure, Map, Date. Thereafter, in reverse direction, a composition of the objects of these types allows generating in memory and quickly writing in file the JSON structure. Thus, reading and writing small JSON volume of previously known structure can be performed with a few code lines.
The main purpose of these tools we see in the information exchange with external systems, reading configuration files in JSON format.
You can perform serialization using the methods of global context ReadJSON() and WriteJSON(). They work together with the objects JSONReader and JSONWriter.
As an example of JSON deserialization, you can consider the reading of array with to objects:

[
	{
		"LastName": "Simpson",
		"FirstName": "Bart",
		"Age": 15
	},
	{
		"LastName": "Simpson",
		"FirstName": "Lisa",
		"Age": 14
	}
]

1С:Enterprise code which executes deserialization can be as follows:

	
        JSONReader = New JSONReader;
	JSONReader.OpenFile("FileName");
	Employees = ReadJSON(JSONReader);
	JSONReader.Close();
	
	For each Employee in Employees Do
		FirstName = Employee.FirstName;	
		LastName = Employee.LastName;	
		Age = Employee.Age;	
	EndDo;

And an example of serialization (writing) in JSON can be as follows:

	
        Str = New Structure;
	Str.Insert("LastName", 	"Simpson");
	Str.Insert("FirstName", "Bart");
	Str.Insert("Age", 	15);
	Str.Insert("IsChild", 	True);
	
	PhoneNumbers = New Array;
	PhoneNumbers.Add("415-6505522");
	PhoneNumbers.Add("415-6505623");
	
	Str.Insert("PhoneNumbers", PhoneNumbers);

	JSONWriter = New JSONWriter;
	JSONWriterSettings = new JSONWriterSettings(, Chars.Tab);
	JSONWriter.OpenFile("FileName",,, JSONWriterSettings);
	WriteJSON(JSONWriter, Str);
	JSONWriter.Close();

A result of writing:

{
	"LastName": "Simpson",
	"FirstName": "Bart",
	"Age": 15,
	"IsChild": true,
	"PhoneNumbers": [
		"415-6505522",
		"415-6505623"
	]
}

Functions for conversion and recovery on serialization

Serialization cannot be always performed fully automatically. There are a variety of situations. Therefore, we have added an ability to use «custom» function for processing the values then writing in JSON and reading from JSON.
In method WriteJSON() it is referred to as Conversion function and is described with three parameters:

  • TransformerFunctionName
  • TransformerFunctionModule
  • TransformerFunctionAdditionalParameters

In method WtireJSON() it is referred to as Recovery function and there are the same parameters for it:

  • ReviverFunctionName
  • ReviverFunctionModule
  • ReviverFunctionAdditionalParameters

When writing in JSON, this function is useful because allows you to convert in JSON yourself those types that cannot be converted automatically. Or even completely abandon their serialization.

For example, it turned out that in the written structure on of the values is a reference to the item of catalog “Subdivisions”. This value (a reference to the 1С:Enterprise object) cannot be automatically serialized using the platform tools. Then, using the conversion function, we can get for this value its string representation in convenient form. For example, in the form of the string “Company Name: Publicity department”.

Procedure WriteToJSON()

	Str = New Structure;
	Str.Insert("LastName", 	"Simpson");
	Str.Insert("FirstName", "Bart");
	Str.Insert("Subdivision", SubdivisionRef);
	
	PhoneNumbers = New Array;
	PhoneNumbers.Add("415-6505522");
	PhoneNumbers.Add("415-6505623");
	
	Str.Insert("PhoneNumbers", PhoneNumbers);

	JSONWriter = New JSONWriter;
	JSONWriterSettings = New JSONWriterSettings(, Chars.Tab);
	JSONWriter.OpenFile("FileName",,, JSONWriterSettings);
	WriteJSON(JSONWriter, Str,, "TransformerFunction", CommonModuleServer);
	JSONWriter.Close();
	
EndProcedure
...
Procedure TransformerFunction(Val Property, Value, AdditionalParameters, Cancel) Export
	
	If TypeOf(Value) = Type("CatalogRef.Subdivisions") Then
		Return Value.Owner.Description + ": " + Value.Description;
	//ElseIf ...
	EndIf;
EndProcedure

A result of example execution:

{
	"LastName": "Simpson",
	"FirstName": "Bart",
	"Subdivision": "Company Name: Publicity department",
	"Phones": [
		"415-6505522",
		"415-6505623"
	]
}

When reading from JSON, the recovery function can be used to convert JSON data into the 1С types that cannot be a result of automatic conversion, or to convert without assistance (not automatically) JSON data into the 1С:Enterprise data.

Serialization of Date type

Data with Date type are serialized in JSON automatically, but the reverse conversion (deserialization) cannot be always performed. JSON does not contain the type Date, the date values a represented in it with a string. Or course, there are some formats to represent the dates, but in general, the appearance of such string can be various.
To serialize a Date type in JSON, you can use in the method WriteJSON() the parameter SerializerSettings. This is a script object which allows you to indicate in which version the date will be written (UTC, local date or local date with offset), as well as in which format (ISO, JavaScript or Microsoft).

1С:Enterprise code:

	Array = New Array;
	Array.Add(New Structure("FullName, BirthDate", "Bart Simpson", Date("19850505000000")));
	Array.Add(New Structure("FullName, BirthDate", "Lisa Simpson", Date("19860103000000")));
	
	JSONWriter = New JSONWriter;
	JSONWriterSettings = New JSONWriterSettings(, Chars.Tab);
	JSONWriter.OpenFile("FileName",,, JSONWriterSettings);
	
	JSONSerializerSettings = New JSONSerializerSettings;
	JSONSerializerSettings.DateWritingVariant = JSONDateWritingVariant.LocalDate;
	JSONSerializerSettings.DateSerializationFormat = JSONDateFormat.ISO;
	
	WriteJSON(JSONWriter, JSONSerializerSettings);
	
	JSONWriter.Close();

JSON text:

[
	{
		"FullName": "Bart Simpson",
		"Birthday": "1985-05-05T00:00:00"
	},
	{
		"FullName": "Lisa Simpson",
		"Birthday": "1986-01-03T00:00:00"
	}
]

But reading the date from JSON is a bit more complicated. In parameter PropertiesWithDateValuesNames you can list those JSON properties the values of which should be converted in the 1С:Enterprise date (type Date). And in parameter ExpectedDateFormat you need to indicate in which format these data are stored in JSON (ISO, JavaScript or Microsoft).
1С:Enterprise code for previous JSON text:

	JSONReader = New JSONReader;
	JSONReader.OpenFile("FileName");
	Employees = ReadJSON(JSONReader,, "BirthDate", JSONDateFormat.ISO);
	JSONReader.Close();
	
	For each Employee in Employees Do
		FullName = Employee.FullName;	
		BirthDate = Employee.BirthDate;	
	EndDo;

However, if it appears that at some point the format of JSON dates does not match the expected format an exception will be called.
In this situation, for greater versatility, you can attach the same JSON properties into array to be processed by the recovery function - PropertyNamesToRevive. And already in the recovery function you deserialize yourself the JSON dates in whatever format they may be presented.

Using JSON in HTTP interfaces of applications

Automatically generated REST interface of application solutions

When addressing to the REST interface of application solution, you can receive a response in JSON format. For this, you need to specify in the address line the parameter $format=json. Or specify a MIME type “application/json” in the header of Accept HTTP request. For example:
Request:

GET /TestInfobase/odata/standard.odata/TestCatalog?$format=json HTTP/1.1
MaxDataServiceVersion: 3.0;NetFx
Accept: application/json
Accept-Charset: UTF-8
User-Agent: Microsoft ADO.NET Data Services

Response:

HTTP/1.1 200 OK
Content-Length: 9429
Content-Type: application/json;charset=utf-8
Server: Microsoft-IIS/7.5
DataServiceVersion: 3.0
X-Powered-By: ASP.NET
Date: Mon, 12 Aug 2013 09:44:07 GMT
    
{
"odata.metadata":"http://host/svc/$metadata#TestCatalog",
"value":[
{
	"Ref_Key":guid'cc6a7df3-8cfe-11dc-8ca0-000d8843cd1b',
	"DataVersion":"AAAAAQAAAAE",	
	"DeletionMark":false,
	"Parent_Key":guid'bbb079ae-8c51-11db-a9b0-00055d49b45e',
	"IsFolder":false,
	"Code":000000025,
	"Description":"String",
	"Supplier_Key":guid'd1cb82a7-8e8b-11db-a9b0-00055d49b45e',
	"Supplier@navigationLinkUrl":"TestCatalog(guid'cc6a7df3-8cfe-11dc-8ca0-000d8843cd1b')/Supplier",
	"ValueStorage_Type": "image/jpeg",
	"ValueStorage_Base64Data@mediaReadLink": "Catalog_TestCatalog(guid'cf2b1a24-1b96-11e3-8f11-5404a6a68c42')/ValueStorage_Base64Data",
	"ValueStorage_Base64Data": 
	…
},
{…},
{…}
]
}

You can control the amount of transmitted information by changing detail of metadata presentation on uploading. There are three levels: NoMetadata, MinimalMetadata and FullMetadata. By default (in the above example), a middle level is used - MinimalMetadata. At the NoMetadata level the amount of transmitted information is minimal and at the level FullMetadata is maximal. However, in this case you must understand that the reduction in the volume of transmitted information leads to more intensive calculations on the client. Inversely, when all the information is attached to the uploading, the amount of calculations on the client will be minimal.

You can specify the detail of metadata presentation, for example, in the address line.
Information about metadata is not transmitted:
GET /TestInfobase/odata/standard.odata/TestCatalog/?$format=application/json;odata= minimalmetadata

All information about metadata is included in the uploading:
GET /TestInfobase/odata/standard.odata/TestCatalog/?$format=application/json;odata=fullmetadata

HTTP-services of application solution

HTTP-services implemented in the application solution can also return a response in JSON format. For this, it is easier for you to generate a response body in JSON, receive it as a string and then generate from this string a body of HTTP response of the service. In this case, it is desirable to indicate that BOM (Byte Order Mark) should not be used.

Function DataGET(Request)
	
	// prepare data
	
	JSONWriter = New JSONWriter;
	JSONWriter.SetString();
	
	//write data to JSON
	///...
	
	JSONString = JSONWriter.Close();
	
	Response = New HTTPServiceResponse(200);
	Response.SetBodyFromString(JSONString, "UTF-8", ByteOrderMarkUsage.DontUse);   
	
	Return Response;
	
EndFunction

The last parameter (ByteOrderMarkUsage.DontUse) you can not specify if the configuration compatibility mode is not set or it is more than Version 8_3_5. Because in this case BOM will automatically be used for the coding UTF-16 and UTF-32. And for UTF-8, UTF-16LE/UTF-16BE, UTF-32LE/UTF-32BE and other it will not be used.

Interaction with third-party HTTP services

When interacting with third-party HTTP interfaces, you may also need to generate the requests for them in JSON format. In this case, the algorithm of your actions will be the same. Generate the request body in JSON. Receive the body as a string. From this string generate the body of HTTP request. Do not use BOM.

JSONString = JSONWriter.Close();

HTTPConnection = New HTTPConnection("Server", "Port");
HTTPRequest = New HTTPRequest("Resource address");
HTTPRequest.SetBodyFromString(JSONString, "UTF-8", ByteOrderMarkUsage.DontUse);

Result = HTTPConnection.Get(HTTPRequest); 
Further development

We are thinking to provide you with the opportunity of JSON serialization of 1С:Enterprise application types: references, objects, record sets, etc. Therefore, it is possible that another level of the tools to work with JSON will appear. This level will allow you to convert in JSON any 1С:Enterprise types for which XDTO-serialization in XML is supported.

Click to rate this post!
[Total: 0 Average: 0]

Leave a Reply

Your email address will not be published. Required fields are marked *