How to work with SOAP services in 1C:Enterprise

Alexander Biryukov

18.08.2020 12 min

We continuously emphasize that 1C has extensive opportunities for integration with other systems. Moreover, an application created in the 1C platform can act as a client (that is, the program can receive data), and as a server (in this case, the program on 1C will send data).

And of course, 1C supports all modern data exchange protocols.

Let's take a look at data exchange using SOAP today.

What is SOAP?

In its most general form, SOAP is a protocol for exchanging structured XML messages in an arbitrarily distributed environment. It follows that we have to transfer XML somewhere and get XML back as well. But to correctly form an XML request and then correctly process the XML response, we must know the rules by which these requests are formed. These rules are described in a particular WSDL format.

Generally - WSDL is a language for describing web services and accessing them based on XML (https://en.wikipedia.org/wiki/Web_Services_Description_Language).

So, our application should be able to generate XML files described by WSDL rules. To simplify this task, 1C has a special object - a WS-reference. Using this object, the programmer can quite simply organize the receipt of data from an external service. 

Let's develop a simple example program that will receive data over SOAP. 

To test our program, we'll need a public service that sends data over the SOAP protocol. If there are many similar services that show the weather forecast, or exchange rates. In our example, we'll use a service that shows brief information on countries of the world (http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL)

If you open this link in a browser, you can see the following picture:

1.png

This file describes the interaction rules for this particular service. Well, it's time to open the Designer 1C:Enterprise and create a new project there.

First, create a new 1C configuration. Next, in the configuration tree, create a new object – WS-reference. Specify a link to the WSDL file as an object parameter:

2.png

3.png

After creating a WS- reference and loading the rules, you can view the set of possible methods and their typed parameter sets. To do this, double-click on the WS reference object:

4.png

So, half of the work is done, we just have to create the program code that will work with this object.

Let's create a common form in which data processing will be performed:

5.png

Set the parameters of the workspace right away so that the common form opens when the program starts:

6

Next, create one command "ListOfContinents" on the form:

7.png

and a table "tableOfContinents" with two columns "ContinentName" and "ContinentCode":

8.png

Now we create the program code for the " ListOfContinents" command:

&AtClient
Procedure ListOfContinents(Command)
        ListOfContinentsAtServer();
EndProcedure

&AtServer
Procedure ListOfContinentsAtServer()

         tableOfContinents.Clear();
         CountryInfoService = WSReferences.WSCountryInfo.CreateWSProxy("http://www.oorsprong.org/websamples.countryinfo","CountryInfoService","CountryInfoServiceSoap12");

         result = CountryInfoService.ListOfContinentsByCode();
              listOfContinents = result.tContinent;

         For Each curElement In listOfContinents Do

                   newContinent = tableOfContinents.Add();

                   newContinent.ContinentName = curElement.sName;
                   newContinent.ContinentCode = curElement.sCode;

         EndDo;

EndProcedure


Pay attention to the line: 

CountryInfoService = WSReferences.WSCountryInfo.CreateWSProxy("http://www.oorsprong.org/websamples.countryinfo","CountryInfoService","CountryInfoServiceSoap12");


The CreateWSProxy command takes three parameters: ServiceNamespace, ServiceName, and PortName:

9.png

After the WS reference is created, the ListOfContinentsByCode method is called, which returns a list of continents. Let's start 1C in interactive mode and check how it works.

Start 1C, the form we previously created with one button "List of continents" opens automatically. We press this button and our previously empty list is filled with the names of the continents:

10.png

Well, the main task complete - we received data from an external service using the SOAP protocol ... But let's complicate the task since the service can return not only a list of continents but also a list of countries and detailed information on each country.

Let's add a table "tableOfCountries" to the main form with columns "CountryName" and "CountryCode":

11.png

and place this table on the form:

12.png

For the table "tableOfContinents" create an event handler "OnActivateRow":

13.png

The program code will look like this:

&AtClient
Procedure tableOfContinentsOnActivateRow(Item)

        If Item.CurrentRow = Undefined Then
                  Return;
        EndIf;

ListOfCountryNamesAtServer(Items.tableOfContinents.CurrentData.ContinentCode);

EndProcedure

&AtServer
Procedure ListOfCountryNamesAtServer(ContinentCode)

         tableOfCountries.Clear();

         CountryInfoService = WSReferences.WSCountryInfo.CreateWSProxy("http://www.oorsprong.org/websamples.countryinfo","CountryInfoService","CountryInfoServiceSoap12");

         result = CountryInfoService.ListOfCountryNamesGroupedByContinent();

         listCountryByContinent = result.tCountryCodeAndNameGroupedByContinent;

         For Each curElement In listCountryByContinent Do

                    curContinent = curElement.Continent;

                    If Not curContinent.sCode = ContinentCode Then
                              Continue;
                    EndIf;

                              curCountryList = curElement.CountryCodeAndNames.tCountryCodeAndName;

                    For Each curCountry In curCountryList Do

                               newCountry = tableOfCountries.Add();

                               newCountry.CountryName = curCountry.sName;
                               newCountry.CountryCode = curCountry.sISOCode;

                    EndDo;

                    Break;

          EndDo;

EndProcedure

First, the current continent code is determined:

Items.tableOfContinents.CurrentData.ContinentCode

Then the tCountryCodeAndNameGroupedByContinent method is called:

listCountryByContinent = result.tCountryCodeAndNameGroupedByContinent

This method returns a list of countries grouped by continent. The program in a loop checks the coincidence of the code of the continent we need and fills in the table only with the countries of this continent:

If Not curContinent.sCode = ContinentCode Then
          Continue;
EndIf;

Let's see what we got. Start 1C in dialog mode, press the "List of continents" button and click on the list of continents. As you can see, the list of countries is filled with the required values:

14


Let's try to get complete information on a specific country. For this, you can use the "FullCountryInfo" method. Please also note that this method takes a parameter as input - the code of the country we need:

15.png

Add the necessary attributes to the main form: "Country name", "Country capital", etc .:

16.png

and for the table "tableOfCountries" create an event handler "OnActivateRow":

17.png

Create the following code:

&AtClient
Procedure tableOfCountriesOnActivateRow(Item)

        If Item.CurrentRow = Undefined Then
                 Return;
        EndIf;

        FullCountryInfoAtServer(Items.tableOfCountries.CurrentData.CountryCode);

EndProcedure

&AtServer
Procedure FullCountryInfoAtServer(CountryCode)

         CountryInfoService = WSReferences.WSCountryInfo.CreateWSProxy("http://www.oorsprong.org/websamples.countryinfo","CountryInfoService","CountryInfoServiceSoap12");

         Try
                  result = CountryInfoService.FullCountryInfo(CountryCode);
         Except
                  Return;
         EndTry;

         CountryName                 = result.sName;
         CountryCapital              = result.sCapitalCity;
         CountryPhoneCode            = result.sPhoneCode;
         CountryCurrency             = result.sCurrencyISOCode;
         CountryLanguages            = GetCountryLanguages(result.Languages.tLanguage);
         ShowPictureFlag(result.sCountryFlag);

EndProcedure

The operation of this code is similar to the one discussed above, so do not dwell on the description of how this code works.

The only thing to notice about the procedures "GetCountryLanguages" and "ShowPictureFlag".

The code for the "GetCountryLanguages" procedure is as follows:

&AtServer
Function GetCountryLanguages(listLanguages)

       result = "";

       For Each curLanguage In listLanguages Do
                  result = result + " " + curLanguage.sName;
       EndDo;

       Return result;

EndFunction

Since some countries may have several state languages, the service returns the value of not one language, but a list of values. This procedure simply converts the list of languages into one string. Perhaps this is not the most elegant solution - but it all depends only on your imagination.


Now let's analyze the program code of the "ShowPictureFlag" procedure:

&AtServer
Procedure ShowPictureFlag(LinkToPicture)

        Connection = New HTTPConnection("www.oorsprong.org");
        tempFileName = GetTempFileName();
        LinkToPicture = StrReplace(LinkToPicture,,"http://www.oorsprong.org","");
        Connection.Get(LinkToPicture, tempFileName);
        pictureFlag = New Picture(tempFileName);
        AddressInTempStorage = PutToTempStorage(pictureFlag, New UUID);
        CountryFlag = AddressInTempStorage;

EndProcedure

The service returns a link to an image of a country flag, something like: http://www.oorsprong.org/WebSamples.CountryInfo/Flags/Guam.jpg


Unfortunately, 1C cannot directly display this image. Therefore, we first download this image from the site. For this, the HTTPConnection object is used. In this case, the resulting image is saved to a temporary file "tempFileName". Then a Picture object is created from a temporary file, which is placed in temporary storage, and only after that, the flag image can be displayed on the main form.

Well, we have completely created the necessary program code. Let's check how it works.

Start 1C again in dialog mode, press the "" button, and then click on continents and countries. In this case, for each country, all information related to this country will be displayed:

18.png

A small addition: 1C allows you to work in WSDL with links directly, without first creating a WS reference object. The source code, in this case, will be slightly different. 

Instead of a line:

CountryInfoService = WSReferences.WSCountryInfo.CreateWSProxy("http://www.oorsprong.org/websamples.countryinfo";,"CountryInfoService","CountryInfoServiceSoap12");

you will need to write the following code:

Definitions               = New WSDefinitions("http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL");

CountryInfoService        = New WSProxy(Definitions,"http://www.oorsprong.org/websamples.countryinfo","CountryInfoService","CountryInfoServiceSoap12");

The second method has both advantages and disadvantages. The advantages include the fact that there is no need to create a new WS object in the 1C configuration. The disadvantage of this method is as follows: with each call from 1C, the service returns its full description, which can negatively affect the performance of highly loaded systems. Therefore, the second method of working with WS objects can be recommended only for testing or prototyping programming interfaces. For real work, you need to use the WS reference object.

OK, it's time to take stock. So, we have created a 1C program that can access a third-party web service and, using the SOAP protocol, receive the necessary data from this service.

Our example is, of course, educational and very simplified, but all real enterprise-level solutions are also based on these foundations.

You can download this Example for your own application.

If you have any questions about this article, you can always get answers on our forum: https://1c-dn.com/forum/

Stay with us. There are still many interesting things ahead

Be the first to know tips & tricks on business application development!

A confirmation e-mail has been sent to the e-mail address you provided .

Click the link in the e-mail to confirm and activate the subscription.