Web service avec SAP PI  +  WSDL  +  Tests

Problématique:

Le SAP rendre disponible des Web Services par PI (Process Integration) pour réaliser des transactions entre les clients et le SAP.

Les clients peuvent être des applications développées sur plusieurs plateformes, en tous cas, pendant le processus du développement du client, il  faut avoir certaines conditions et disponibilités:

  • instance du SAP/PI configuré;
  • bonnes données pour les tests;
  • contrôle du temps de réponse;

Le WSDL est le point de départ du développement du client.

Dans ce cas, le client est développé en C#.

Les étapes d’utilisation:

1. Créer un projet et ajouter un “Web Reference” par “Service Reference”;

 1
 2using ConsoleWSDL.MyWebServiceName;
 3
 4namespace ConsoleWSDL
 5
 6{
 7
 8    static class Program
 9
10    {
11
12        static void Main(string[] args)
13
14        {
15
16            using (MyWebServiceName.TestService service = new MyWebServiceName.TestService())
17
18            {
19
20                // Initialisation
21
22                var d = new DT_Param
23
24                {
25
26                    EDI_DC20 = new DT_Param_DC20 {SERIAL = "123"}
27
28                };
29
30                // Call web service
31
32                var ret = service.Test(d);
33
34            }
35
36        }
37
38    }
39
40}

Dans ce moment, on peut finir notre exercice, et développer le code pour le traitement des paramètres et de la réponse selon le WSDL utilisé.

Par contre, il faut avoir la disponibilité du SAP et des données valides.

Deuxième problème: Un nouveau code a besoin de beaucoup de tests, et la certitude de réponses prévisibles et contrôlées;

Alors, on essaie de remplacer les incertitudes causées par l’utilisation du SAP et avoir contrôlé sur les réponses du Web Service.

Solution proposée: Creer un “Web Service” qui remplace le SAP Web Service.

Créer une classe avec la définition du WSDL

 1
 2private static string ConvertWSDL_To_WSClass(string textWsdl, string protocol)
 3
 4{
 5
 6        byte[] byteArray = Encoding.UTF8.GetBytes(textWsdl);
 7
 8        MemoryStream stream = new MemoryStream(byteArray);
 9
10        ServiceDescription wsdlDescription = ServiceDescription.Read(stream); ;
11
12        ServiceDescriptionImporter wsdlImporter = new ServiceDescriptionImporter();
13
14        wsdlImporter.ProtocolName = protocole;  // Soap | Soap12
15
16        wsdlImporter.AddServiceDescription(wsdlDescription, null, null);
17
18        wsdlImporter.Style = ServiceDescriptionImportStyle.Server;
19
20        wsdlImporter.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties;
21
22        CodeNamespace codeNamespace = new CodeNamespace();
23
24        CodeCompileUnit codeUnit = new CodeCompileUnit();
25
26        codeUnit.Namespaces.Add(codeNamespace);
27
28        ServiceDescriptionImportWarnings importWarning = wsdlImporter.Import(codeNamespace, codeUnit);
29
30        if (importWarning != 0) return importWarning.ToString();
31
32        StringBuilder stringBuilder = new StringBuilder();
33
34        StringWriter stringWriter = new StringWriter(stringBuilder);
35
36        CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
37
38        codeProvider.GenerateCodeFromCompileUnit(codeUnit, stringWriter, new CodeGeneratorOptions());
39
40        stringWriter.Close();
41
42        return stringBuilder.ToString();
43
44}

Il faut vérifier si le WSDL utilise le protocole SOAP 1.1 ou SOAP 1.2

Creer un projet “Web Application” vide pour ajouter le Web Service de test.

Voici le code créé que l’on va changer:

 1
 2using System.Web.Services;
 3
 4namespace WebApplicationTest
 5
 6{
 7
 8    /// <summary>
 9
10    /// Summary description for WebServiceTest
11
12    /// </summary>
13
14    [WebService(Namespace = "<a href="http://tempuri.org/">http://tempuri.org/</a>")]
15
16    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
17
18    [System.ComponentModel.ToolboxItem(false)]
19
20    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
21
22    // [System.Web.Script.Services.ScriptService]
23
24    public class WebServiceTest : System.Web.Services.WebService
25
26    {
27
28        [WebMethod]
29
30        public string HelloWorld()
31
32        {
33
34            return "Hello World";
35
36        }
37
38    }
39
40}

1. Changer l’héritage de la classe avec la classe créée avec la définition du WSDL;

2. Ajouter la méthode interne de la classe;

3. Ajouter les qualifications  :

        [System.Web.Services.WebMethodAttribute()]

[System.Web.Services.Protocols.SoapDocumentMethodAttribute(“http://sap.com/xi/WebService/soap1.1")]

Voici le code modifié:

 1
 2using System;
 3
 4using System.Web.Services;
 5
 6namespace WebApplicationTest
 7
 8{
 9
10    /// <summary>
11
12    /// Summary description for WebServiceTest
13
14    /// </summary>
15
16    [WebService(Namespace = "<a href="http://tempuri.org/">http://tempuri.org/</a>")]
17
18    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
19
20    [System.ComponentModel.ToolboxItem(false)]
21
22    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
23
24    // [System.Web.Script.Services.ScriptService]
25
26    public class WebServiceTest : TestServiceService
27
28    {
29
30        [System.Web.Services.WebMethodAttribute()]
31
32        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://sap.com/xi/WebService/soap1.1")]
33
34        public override string TestService(DT_Param_DC20 MT_Param_DV20)
35
36        {
37
38            throw new <strong>NotImplementedException</strong>();
39
40        }
41
42    }
43
44}

Il faut ajouter le traitement nécessaire à la fonctionnalité désirée du “Web Service” selon le cas, la réponse peut être une valeur constante pour l’aider le développement du code de la communication vers le SAP.

Finalement, pour utiliser le test, on doit changer l’URL vers le Web Service de test.

Voici le code modifié:

 1
 2using ConsoleWSDL.MyWebServiceName;
 3
 4namespace ConsoleWSDL
 5
 6{
 7
 8    static class Program
 9
10    {
11
12        static void Main(string[] args)
13
14        {
15
16            using (MyWebServiceName.ConfirmationTimeTicket_AsyncService service = new MyWebServiceName.ConfirmationTimeTicket_AsyncService())
17
18            {
19
20                // My new address to test
21
22                service.Url = "<a href="http://localhost:1234/WebServiceTest.asmx">http://localhost:1234/WebServiceTest.asmx</a>";
23
24                // Initialisation
25
26                var d = new DT_ConfirmationTimeTicket
27
28                {
29
30                    EDI_DC40 = new DT_ConfirmationTimeTicketEDI_DC40 {SERIAL = "123"}
31
32                };
33
34                // Call web service
35
36                service.ConfirmationTimeTicket_Async(d);
37
38            }
39
40        }
41
42    }
43
44}

* Attention : si l’on ajoute des lignes ou des espaces dans le fichier du WSDL, on peut avoir des erreurs pour créer la classe du Web Service.

sources: https://code.msdn.microsoft.com/Generating-a-Web-Service-95ff4e10

http://www.codeproject.com/Articles/172725/Integrating-SAP-Web-Services-into-Microsoft-NET-En

http://forums.asp.net/t/1204267.aspx?Server+did+not+recognize+the+value+of+HTTP+Header+SOAPAction