6.2 Creation of X-Road dataservice and client based on WSDL (.NET platform)

Environment: Windows OP, .NET framework(3.5+), IIS(7+)

https://www.microsoft.com/en-us/download/search.aspx?q=.net%20framework

Tools: MS Visual Studio (2010+) Professional/Ultimate/..,

https://www.visualstudio.com/post-download-vs/?sku=pro&clcid=0x409&telem=ga

SoapUI https://www.soapui.org/downloads/soapui.html

Frameworks: WCF

Method: ‘Top Down’ – generation of C# code based on available WSDL.

6.2.1 Preparation

Preparation of the operating environment of the application – Internet Information Services (IIS).

First check if all necessary Windows components are activated. Otherwise install/add the lacking components. Open by using Control Panel Programs and Features and select Turn Windows features on or off.

Switch on the following components:

  • Common HTTP Features
    • Directory Browsing and Static Content

As the development of the interfacing component takes place with the ‘Top Down’ method, the WSDL file of the dataservice must be published on the server. By adding this component, we grant to the security server access to static files. This is used by users of the service as well as security server administrators.

  • Application Development Features
    • .NET Extensibility
    •  ASP.NET

X-Road security servers do not transmit SOAPAction header. Therefore, it must be assumed that interfacing components manage incoming SOAP messages by body sub-element. An extension must be added in the WCF framework which enables the same behaviour, SOAPAction header is used by default. A description of the solution to this problem will be provided below.

  • .NET Framework Advanced Services
    • ASP.NET
    • WCF Services
    • HTTP Activation

Note! WCF or ASP.NET services may generate the WSDL
  file automatically if a request is submitted to the address 
http://localhost:port/teenusenimi?wsdl.
However, automatically generated files lack
  obligatory elements of the X-Road namespace. Therefore, the original service
  description file used for generating the code must be published. 

For the realisation of the described steps, the following console command can also be used to install all necessary components.

For the realisation of the described steps, the following console command can also be used to install all necessary components:
start
  /w pkgmgr /iu:IIS-WebServerRole;IIS-WebServer;IIS-CommonHttpFeatures;IIS-StaticContent;IIS-DefaultDocument;IIS-DirectoryBrowsing;IIS-HttpErrors;IIS-HttpRedirect;IIS-ApplicationDevelopment;IIS-ASPNET;IIS-NetFxExtensibility;IIS-ASP;IIS-CGI;IIS-ISAPIExtensions;IIS-ISAPIFilter;IIS-ServerSideIncludes;IIS-HealthAndDiagnostics;IIS-HttpLogging;IIS-LoggingLibraries;IIS-RequestMonitor;IIS-HttpTracing;IIS-CustomLogging;IIS-ODBCLogging;IIS-Security;IIS-BasicAuthentication;IIS-WindowsAuthentication;IIS-DigestAuthentication;IIS-ClientCertificateMappingAuthentication;IIS-IISCertificateMappingAuthentication;IIS-URLAuthorization;IIS-RequestFiltering;IIS-IPSecurity;IIS-Performance;IIS-HttpCompressionStatic;IIS-HttpCompressionDynamic;IIS-WebServerManagementTools;IIS-ManagementConsole;IIS-ManagementScriptingTools;IIS-ManagementService;IIS-IIS6ManagementCompatibility;IIS-Metabase;IIS-WMICompatibility;IIS-LegacyScripts;IIS-LegacySnapIn;IIS-FTPPublishingService;IIS-FTPServer;IIS-FTPManagement;WAS-WindowsActivationService;WAS-ProcessModel;WAS-NetFxEnvironment;WAS-ConfigurationAPI

6.2.2 Creation of X-Road dataservice

Precondition: persons_register.wsdl service description file is completed and WcfExtensions.dll (or its source code from GitHub) is downloaded.

6.2.3 Preparation of application

We generate a workspace in Visual Studio, where we start making the application. The first application is an interfacing component of the service provider or Producer, for which we use the WCF Service Application template.

We create a new project and select the required template:

Delete:

  • IService1.cs,
  • Service1.svc
  • Service1.svc.cs

the files to have a clean application, and add necessary files. For the service description file, we should create a directory with the name ‘wsdl’ and add the previously prepared WSDL file into it.

Create a directory:

Select the project Producer and challenge the context menu and select Add->New Folder-> folder name: wsdl

Add an extension file:

Select the project Producer and challenge the context menu and select Add->Existing item-> WSDL file.

Add a reference to the .dll file:

References-> in the context menu, Add reference-> in the displayed window Reference Manager, select Assemblies->Browse-> select WcfExtensions.dll file.

Note! To prevent losing the added file during
  IIS publishing, properties of the file must be changed as follows:
  Build Action->Content
  Copy to Output Directory->Copy always

 

If the application has all components, you can start writing the code. First, it is necessary to create service interface and data model classes. There are several options to do this:

  1. Use the programme svcutil.exe on the command line and add the created files to the application. If it is necessary to change the interface code, repeat the operation.
  2. Activate the following command on the command line:

svcutil/l:cs /o:IPersonService.cs /noConfig person_register.wsdl

/l: - Language, by default CSharp

/o: - Result file name, by default WSDL file name

/noConfig – Configuration file is not required

The last parameter is WSDL file name

Add the result into the project folder

3. Use Visual Studio’s user interface (which in turn uses svcutil.exe).

    • Click the References button of the project subdirectory
    • In the context menu, select Add service reference
    • In the field Address, enter the file name of the service description with a directory name

e.g.: F:\Workspace\NET\XRoad\Samples\Producer\wsdl\person_register.wsdl

    • Enter a suitable name for the namespace of service objects in the field Namespace.

e.g.: pplService

    • Click the Advanced button
    • Ensure that Allow generation of asynchronous operations check box is not ticked (X-Road does not support asynchronous methods)
    • Tick the check box Always generate message contracts
    • Click OK

As a result of this step, pplService folder should be created under the Service Reference directory.

Note!
In the future, if WSDL file has been changed and data types also need updating,
pplService must be selected in the application in Service Reference directory
and Configure Service Reference ... in context menu, and then select OK.
Thus, svcutil.exe programme is activated and code is created from zero.

This way, service client code is added to the application, and the first steps are similar when creating a service client application.

Why does a service provider need this? For creating a service interface and classes of objects used in the service.

Created objects can be viewed in Object Browser:

  1. Interface of service provider
  2. Class of the user of service
  3. Objects in the service
  4. Objects of service request and X-Road message headers.

Note!
After adding service reference, the element <client> appears in Web.conf file.
As the service provider does not use it, this can be removed.

<configuration>

  <system.serviceModel>
    …
    <client>
      <endpoint address="http://localhost:8080/person_register/services/person_registerSOAP"
        binding="basicHttpBinding" bindingConfiguration="person_registerSOAP"
        contract="pplService.person_register" name="person_registerSOAP" />
    </client>


6.2.4 Implementing the service

Add the file realising the service interface:

In the application context menu, select ‘Add’ -> ‘New Item ...’ -> ‘WCF Service’ -> PeopleRegister.svc (IPeopleRegister.cs file is not necessary and it can be deleted).

using System;
using Producer.pplService;
 
namespace Producer
{
    public class PeopleRegister : pplService.person_register
    {
        public personListResponse personList(personListRequest1 request)
        {
            throw new NotImplementedException();
        }
    }
}

Add a simple realisation to personList, where headers are copied and a static response is returned:

public personListResponse personList(personListRequest1 request)
{
    return new personListResponse
    {
        client = request.client,
        service = request.service,
        id = request.id,
        protocolVersion = request.protocolVersion,
        userId = request.userId,
        response = new personListResponseResponse
        {
            person = new person
            {
                birthDate = DateTime.Now,
                firstName = "Juhan",
                lastName = "Tamm",
                personContact = new contact{
                    address = "Metsa 12",
                    email = new []{
                        "juhan@ee.ee"
                    },
                    phone = new []{
                        "333333"
                    }
                }
            }
        }
    };

 

The service can return a simple static response, and in order to change the management method of WCF messages, we add a DispatchByBodyElementBehavior attribute to the class realising the service, which enables to register operations in request administrator list. Each operation must be separately marked with the attribute DispatchBodyElement with two arguments:

personList – name of the root element of a SOAP message (name of service operation)

http://persons_register.x-road.ee – namespace of service provider (same as in WSDL file).

[DispatchByBodyElementBehavior]
public class PeopleRegister : pplService.person_register
{
    [DispatchBodyElement("personList", "http://persons_register.x-road.ee")]
    public personListResponse personList(personListRequest1 request)
    {
        ...
    }
}

Furthermore, a WCF extension must be registered in the Web.Conf file. For changing the configuration file, it is possible to use the interface Microsoft Service Configuration Editor integrated in Visual Studio. Select file Web.config and in the context menu Edit WCF Configuration.

Note! Before using Type Browser, the application must be compiled. Type Browser parses compiled files to find type classes. Therefore, it may lack recently created classes.

  1. Register new extension
    1. Select Advanced->Extensions->behavior element extensions->New ...
    2. Column Name:CustomMessageFilter.
    3. In column Type, select EndpointBehaviorExtension type located in WcfExtensions.dll
  2. Create a new service Endpoint Behavior by using a registered extension
    1. Select Advanced->Endpoint Behaviors-> New Endpoint Behavior Configuration
    2. Name:CustomMessageFilterBehavior
    3. In the area Behavior element extension position click Add ...
    4. Add CustomMessageFilter element.
  3. Register service endpoint
    1. Service->Create a New service
    2. Service type– click Browse … and select Producer.PeopleRegister type in Producer.dll
    3. Next
    4. Contract field must be automatically filled.
    5. Next
    6. Select New binding configuration
    7. Communication mode: HTTP
    8. Method of interoperability: Basic Web Services interoperability
    9. Leave the field Address empty
    10. Finish
  4. Specify already created Endpoint Behaviour for new service endpoint.
    1. Service->Producer.PeopleRegister->Endpoints->(Empty Name)
    2. BehaviorConfiguration: CustomMessageFilterBehavior
  5. Save the settings
    1. File -> Save

After these steps, Web.config file must include the following element:

  <system.serviceModel>
    <services>
      <service name="Producer.PeopleRegister">
        <endpoint address="" behaviorConfiguration="CustomMessageFilterBehavior"
          binding="basicHttpBinding" bindingConfiguration="" contract="pplService.person_register" />
      </service>
    </services>
    <extensions>
      <behaviorExtensions>
        <add name="CustomMessageFilter" type="WCFExtensions.Helpers.Filters.FilteringEndpointBehaviorExtension, WcfExtensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </behaviorExtensions>
    </extensions>
    <bindings>
      <basicHttpBinding>
        <binding name="person_registerSOAP" />
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="CustomMessageFilterBehavior">
          <CustomMessageFilter />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>   
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

Dataservice is completed. After activating the application, the following view must be displayed:

6.2.5 Publish service on IIS server

Before using the service it must be placed on a IIS server:

Note! In order to publish application successfully on a IIS server, it must be activated as a user with administrator rights. 

  1. Compile the application
    1. Select an application file and in the context menu click Publish. Publish Web window appears.
    2. Select Custom and name the profile.
    3. Publish method:File System
    4. Target location: create and select new directory in IIS application folder e.g.: C:\inetpub\wwwroot\persons
    5. Next
    6. Configuration: Release
    7. Next->Publish
  2. Create a new directory on the IIS server.
    1. Open IIS Manager
    2. In the Sites context menu, select Add Website. A new window appears where directory configuration must be entered
    3. Sitename: persons
    4. Application Pool: select the pool where .NET framework version is the same/later than the application target framework.
    5. Physical path: folder selected in step 1.d
    6. IP address: IP address of the local machine
    7. OK

After these steps, service should be available from the IIS server of the local machine. (e.g.: http://172.25.200.47/PeopleRegister.svc)

6.2.6 Creation of X-Road client application

Add the new application under the existing solution with which service will be used (using e.g. Console Application template). First, add a reference to our service and generate the client code and the objects of data model. There are several options for doing this:

Use the command line in the programme vcutil.exe and add the resulting files to the application. If the interface code should be changed, the operation must be repeated.
1. Activate the following command on the command line:

svcutil /l:cs /o:IPersonService.cs /noConfig person_register.wsdl

/l: – Language, by default Csharp
/o: – Result file name, by default WSDL file name
/noConfig – Configuration file is not required. The last parameter is the WSDL file name
2. Use the Visual Studio user interface.
  • Click the References button of the project subdirectory
  • In the context menu, select Add service reference.
  • In the field Address, enter the URL of the service description file from the local machine e.g.: http://172.25.200.47/wsdl/person_register.wsdl
Note! Now we contact our local service provider directly. Usually, the dataservice description file from the security server must be used when creating an interfacing component.

  • Enter a suitable name for the namespace of objects of the service in the field Namespace. e.g.: pplService
  • Click the Advanced button
  • Ensure that the Allow generation of asynchronous operations check box is not ticked
  • Tick the check box Always generate message contracts
  • Click OK

Now it is possible to create the object of the client and challenge the service methods. We use the following parameters for challenging the service:

  1. Service/xRoadInstance: ee-dev (operate in the X-Road development instance)
  2. Service/ memberClass: COM
  3. Service/ memberCode: <XRD_MEMBER>
  4. Service/ subsystemCode: <TRAINING_PROVIDER_XX>
  5. Service/ serviceCode: <name of dataservice>
  6. Service/ serviceVersion: <dataservice version no>
  7. protocolVersion: 4.0
  8. client /xRoadInstance: ee-dev (tegutseme X-tee arendusekeskkonnas)
  9. client / memberClass: COM
  10. client / memberCode: <XRD_MEMBER>
  11. client / subsystemCode: <TRAINING_CONSUMER_XX>


class Program{
    static void Main(string[] args) {
        //Create header objects
        var protocolVersion = "4.0";
        var id = Guid.NewGuid().ToString();
        var userId = "EE37007160274";
        var service = new XRoadServiceIdentifierType {
            xRoadInstance = "ee-dev",
            memberClass = "COM",
            memberCode = "11333578",
            subsystemCode = "aktorstest-db01",
            serviceCode = "personList",
            serviceVersion = "v1",
            objectType = XRoadObjectType.SERVICE
        };
        var client = new XRoadClientIdentifierType {
            xRoadInstance = "ee-dev",
            memberClass = "COM",
            memberCode = "11333578",
            subsystemCode = "misp2-01",
            objectType = XRoadObjectType.SUBSYSTEM
        };
 
        var request = new personList {
            request = new personListRequest {
 
                givenName = "",
                surname = "Tamm"
            }
        };
        //Create client object
        var serviceClient = new pplService.aktorstestPortTypeClient();
 
        //Make service call
        var response = serviceClient.personList(
            client: ref client,
            service: ref service,
            protocolVersion: ref protocolVersion,
            id: ref id,
            userId: ref userId,
            personList1: request);
 
         
    }
 
}



Viimati muudetud: teisipäev, 16. mai 2017, 16:04