venerdì 2 agosto 2013

AX 2012 - Creazione servizio AIF e consumo tramite C#

In questo articolo vediamo come creare un servizio AIF, esporlo e consumarlo tramite un'applicazione C#, il servizio legge un file CSV e scrive i dati un una tabella. L'articolo è tratto dal white paper Microsoft Dynamics AX 2012 Services.pdf. La tabella di destinazione contterrà due campi, un campo itemid ed un campo itemname Iniziamo creando la classe datacontract del nostro servizio, che chiameremo CRImportaDataContract che si occuperà di fare il parm del filepath:

 [DataContractAttribute('Import')] 
 public class CRImportDataContract 
 { 
   Filename  file; 
 } 

 [DataMemberAttribute('File')] 

 public Filename parmFilename(Filename _file = file) 
 { 
   ; 
   file = _file; 
   return file; 
 } 

 private static CRImportDataContract construct() 
 { 
   return new CRImportDataContract(); 
 } 

 public static CRImportDataContract newFromFile(Filename _file) 
 { 
   CRImportDataContract contract = CRImportDataContract::construct(); 
   ; 

   contract.parmFilename(_file); 
   return contract; 

 } 



A questo punto creimano la classe del servizio che chiameremo CRImportService, settando poi la proprieta RunOn su "Server". La classe contiene il metodo che leggendo il file scrive i dati nella tabella.

 public class CRImportService  
 {  
 }  
 [SysEntryPointAttribute(true)]  
 public CRImportDataContract getFileName(Filename _file)  
 {  
   CRImportDataContract contract;  
   ;  
   contract = CRImportDataContract::newFromFile(_file);  
   return contract;  
 }  
 [SysEntryPointAttribute(true)]  
 public boolean insertIntoTable(Filename _file)  
 {  
   TextIo          inFile;  
   container        line;  
   Counter         records;  
   //SysOperationProgress   simpleProgress;  
   container        fileContainer;  
   Counter         loopCounter;  
   CRTestTable       CRTestTable;  
   boolean         ret;  
   str           filename;  
   #OCCRetryCount  
   #AviFiles  
   filename = _file;  
   try  
   {  
    //Caricamento file per righe, ogni riga è memorizzata in un container  
    inFile = new TextIo(filename, 'r');  
    inFile.inRecordDelimiter('\n');  
    inFile.inFieldDelimiter(';');  
    while (inFile.status() == IO_Status::OK)  
    {  
     fileContainer += [infile.read()];  
    }  
    inFile = null;  
   }  
   catch  
   {  
    //throw error(strFmt("@SYS18678", filename));  
    return false;  
   }  
   //simpleProgress = SysOperationProgress::newGeneral(#aviUpdate, "Importazione...", conLen(fileContainer));  
   ttsBegin;  
   records = 0;  
   //il ciclo parte da 2 perchè si suppone che la prima riga sia di intestazione  
   for (loopCounter = 2; loopCounter <= conLen(fileContainer) - 1 ; loopCounter++)  
   {  
    CRTestTable.clear();  
    //simpleProgress.incCount();  
    try  
    {  
     line = conPeek(fileContainer, loopCounter); // lettura della riga i-esima  
     CRTestTable.ItemId      = conPeek(line, 1);  
     CRTestTable.ItemName     = conPeek(line, 2);  
     CRTestTable.insert();  
     records++;  
     //simpleprogress.setText(strfmt("@SYS76835", loopCounter, CRTestTable.RecId));  
    }  
    catch (Exception::Deadlock)  
    {  
     if (xSession::currentRetryCount() < #RetryNum)  
     {  
      retry;  
     }  
      else  
        return false;  
    }  
   }  
   ttsCommit;  
   //info(strFmt("Inseriti %1 record", records));  
  return true;  
 }  

Dobbiamo ora deployare il servizio:
  1. Tasto destro sul nodo service group dell' AOT, nuovo service group
  2. Nelle proprietà immettere il nome del servizio per es ImportService
  3. Tasto desto sul nodo service group dell'AOT,  new service node reference
  4. Impostare il valore della proprietà Service col valore ImportService
  5. Tasto desto sul nodo service group a cliccare su Deploy service group
Se tutto è andato a buon fine andando in System administration | setup | Service and Application Integration Framework | Inbound ports dovremmo avere il nostro servizio pronto per essere utilizzato



Scriviamo ora una piccola applicazione consolo C# che cunsuma il servizio. Aprire visual studio creare una nuova console application. Click col desto su service reference -> add service reference, Nella finestra che si apre inseriamo nel campo address l'indirizzoil valore del campo URI WSDL che troviamo nelle inboud ports di AX e clicchiamo su Go.


 Ora il servizio è pronto per essere riahiamato via C#:

 string theFile = "C:\\Users\\AXService\\Desktop\\test2.csv";  
 bool insert;  
 ImportServiceClient theService = new ImportServiceClient();  
 CallContext theContext = new CallContext();  
 theContext.Company = "CEU";  
 theContext.Language = "it";  
 theContext.LogonAsUser = "AXService";  
 insert = theService.insertIntoTable(theContext, theFile);  
 Console.WriteLine("Terminato!");     
 Console.Read();