> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Exemple de traitement automatique

> Découvrez pas à pas un exemple d’API ABBYY FlexiCapture qui ouvre une session, crée un lot, téléverse des images de demandes d’ouverture de compte bancaire, les traite et lit les résultats.

Cet exemple montre comment téléverser vers le serveur des demandes d’ouverture de compte bancaire et en extraire les données clients.

<div id="what-the-example-does">
  ## Ce que fait l’exemple
</div>

L’exemple de code effectue les étapes suivantes :

* Se connecte au service
* Ouvre une session
* Ouvre le projet
* Crée un nouveau lot
* Ajoute des images au lot
* Lance le traitement du lot
* Récupère les résultats et affiche les données capturées
* Ferme la session

<div id="set-up-the-example">
  ## Configurer l’exemple
</div>

<Steps>
  <Step title="Téléverser le fichier de projet sur le serveur">
    Téléversez le fichier de projet `UnattendedExample.fcproj` sur le serveur.
  </Step>

  <Step title="Ouvrir la solution dans Visual Studio">
    Ouvrez `UnattendedExample.sln` dans Visual Studio 2013 ou une version ultérieure.
  </Step>
</Steps>

<div id="connect-to-the-service">
  ## Se connecter au service
</div>

```csharp theme={null}
// Créer une instance du client de service web
var service = new FlexiCapture.FlexiCaptureWebServiceSoapClient();
// ======= AUTHENTIFICATION DE BASE =======
// service.ClientCredentials.UserName.UserName = "username";
// service.ClientCredentials.UserName.Password = "password";
```

<div id="open-a-session">
  ## Ouvrir une session
</div>

```csharp theme={null}
// Pour sécuriser vos lots contre les accès non autorisés, spécifiez l'utilisateur actuel
// Tout d'abord, récupérez le nom de l'utilisateur visible par le système
var username = service.GetCurrentUserIdentity();
// Ensuite, retrouvez votre compte parmi les utilisateurs FlexiCapture
var userId = service.FindUser(username.Name);
if (userId <= 0) throw new Exception("Current user not found");
// Ouvrez une nouvelle session de traitement
const int roleType = 12; //Le rôle d'opérateur sur le poste de l'utilisateur
const int stationType = 10; //Le poste de l'utilisateur
var sessionId = service.OpenSession(roleType, stationType);
if (sessionId <= 0) throw new Exception("Couldn't open the session");
```

<div id="open-the-project">
  ## Ouvrir le projet
</div>

```csharp theme={null}
// Récupérer les projets
var projects = service.GetProjects();
var projectGuid = "";
if (projects != null && projects.Count > 0)
{
    foreach (var project in projects)
    {
        if (project.Name != "UnattendedExample") continue;
        projectGuid = project.Guid;
        break;
    }
}
if (string.IsNullOrEmpty(projectGuid))
{
    throw new Exception("Can't find the UnattendedExample project. You must upload this project to the server to be able to work with this example.");
}
// Ouvrir le premier projet nommé UnattendedExample
var projectId = service.OpenProject(sessionId, projectGuid);
if (projectId <= 0) throw new Exception("Couldn't open the project");
```

<div id="create-a-new-batch">
  ## Créer un nouveau lot
</div>

```csharp theme={null}
// Spécifier un nom pour le nouveau lot et laisser les autres propriétés inchangées
var batch = new FlexiCapture.Batch { Name = "Sample API Batch" };
var batchId = service.AddNewBatch(sessionId, projectId, batch, userId);
if (batchId <= 0) throw new Exception("Couldn't create the batch");
```

<div id="add-images-to-the-batch">
  ## Ajouter des images au lot
</div>

```csharp theme={null}
// Ouvrir le lot dans lequel ajouter des images
service.OpenBatch(sessionId, batchId);
```

<div id="upload-files-smaller-than-256-kb">
  ### Téléverser des fichiers de moins de 256 Ko
</div>

```csharp theme={null}
service.AddNewImage(sessionId, batchId, new FlexiCapture.File()
{
    Bytes = File.ReadAllBytes(filename),
    Name = filename
});
```

<div id="upload-larger-files">
  ### Téléversement de fichiers plus volumineux
</div>

Téléverser intégralement en Base64 des fichiers de plus de 256 Ko présente les inconvénients suivants :

* La charge réseau augmente de 33 %.
* Les très grandes requêtes peuvent être bloquées par IIS ou par le pare-feu.
* Si la connexion est interrompue ou en cas d’erreurs réseau, vous devez renvoyer le fichier.

Le téléversement de fichiers via l’API de service de fichiers est bien plus efficace :

```csharp theme={null}
var doc = new FlexiCapture.Document { BatchId = batchId };
var file = new FlexiCapture.File { Name = filename };
var documentId = service.AddNewDocument(sessionId, doc, file, false, 0);
UploadFile(service, sessionId, projectId, batchId, documentId, filename).Wait();
```

<div id="upload-a-file-to-the-server">
  #### Téléverser un fichier vers le serveur
</div>

La méthode `UploadFile` lit le fichier et l’envoie au service de fichiers par blocs de 1 Mo, puis vérifie le téléversement à l’aide d’une somme de contrôle :

```csharp theme={null}
private static async Task UploadFile(FlexiCapture.FlexiCaptureWebServiceSoapClient service, int sessionId, int projectId,
    int batchId, int documentId, string filename)
{
    const int objectType = 0;
    var crc = new Crc32();
    using (var fs = File.OpenRead(filename))
    {
        // Téléversement du fichier par blocs de 1 Mo
        var buffer = new byte[0x100000];
        var readed = fs.Read(buffer, 0, buffer.Length);
        var checksum = crc.Next(buffer, 0, readed);
        if (readed < buffer.Length)
        {
            // Téléversement des petits fichiers en entier
            var resp = await FileRequest(service, "Save", objectType, sessionId, projectId, batchId, 0, documentId, 0, filename, 0,
                new ByteArrayContent(buffer, 0, readed));
            if (resp.StatusCode != HttpStatusCode.OK) throw new Exception("Server error");
        }
        else
        {
            var offset = 0;
            while (readed > 0)
            {
                var action = offset == 0 ? "BeginSaveChunked" : "Append";
                await FileRequest(service, action, objectType, sessionId, projectId, batchId, 0, documentId, 0, filename,
                    offset, new ByteArrayContent(buffer, 0, readed));
                offset += readed;
                readed = fs.Read(buffer, 0, buffer.Length);
                checksum = crc.Next(buffer, 0, readed);
            }
            var resp = await FileRequest(service, "Commit", objectType, sessionId, projectId, batchId, 0, documentId, 0, filename);
            if (resp.StatusCode != HttpStatusCode.OK) throw new Exception("Server error");
        }
        var response = await FileRequest(service, "Checksum", objectType, sessionId, projectId, batchId, 0, documentId, 0, filename);
        var text = await response.Content.ReadAsStringAsync();
        if (uint.Parse(text, NumberStyles.HexNumber) != checksum)
        {
            throw new Exception("An error occurred when uploading the file");
        }
    }
}
```

<div id="send-a-file-request-with-file-content">
  #### Envoyer une requête de fichier avec le contenu du fichier
</div>

La méthode `FileRequest` a deux surcharges qui envoient une action au service de fichiers. La première envoie le contenu du fichier sous forme de données de formulaire multipart :

```csharp theme={null}
private static async Task<HttpResponseMessage> FileRequest(FlexiCapture.FlexiCaptureWebServiceSoapClient service, string action,
    int objectType, int sessionId, int projectId, int batchId, int parentId, int objectId, int version, string streamName, int offset, HttpContent file)
{
    var creds = CredentialCache.DefaultNetworkCredentials;
    if (!string.IsNullOrEmpty(service.ClientCredentials.UserName.UserName))
        creds = new NetworkCredential(service.ClientCredentials.UserName.UserName, service.ClientCredentials.UserName.Password);
    using (var handler = new HttpClientHandler { Credentials = creds })
    using (var client = new HttpClient(handler))
    {
        var uri = service.Endpoint.Address.Uri;
        var content = new MultipartFormDataContent
        {
            {new StringContent(action), "Action"},
            {new StringContent(objectType.ToString()), "objectType"},
            {new StringContent(sessionId.ToString()), "sessionId"},
            {new StringContent(projectId.ToString()), "projectId"},
            {new StringContent(batchId.ToString()), "batchId"},
            {new StringContent(parentId.ToString()), "parentId"},
            {new StringContent(objectId.ToString()), "objectId"},
            {new StringContent(version.ToString()), "version"},
            {new StringContent(Convert.ToBase64String(Encoding.Unicode.GetBytes(streamName))), "streamName"},
        };
        if (offset > 0)
        {
            content.Add(new StringContent(offset.ToString()), "offset");
        }
        content.Add(file, "blob", "data.txt");
        return await client.PostAsync(uri.OriginalString.Replace("/API/v1/Soap", "/FileService/v1"), content);
    }
}
```

<div id="send-a-file-request-without-file-content">
  #### Envoyer une requête de fichier sans inclure le contenu du fichier
</div>

La seconde surcharge envoie une requête sans inclure le contenu du fichier, à l’aide de l’encodage d’URL de formulaire :

```csharp theme={null}
private static async Task<HttpResponseMessage> FileRequest(FlexiCapture.FlexiCaptureWebServiceSoapClient service, string action,
    int objectType, int sessionId, int projectId, int batchId, int parentId, int objectId, int version, string streamName)
{
    var creds = CredentialCache.DefaultNetworkCredentials;
    if (!string.IsNullOrEmpty(service.ClientCredentials.UserName.UserName))
        creds = new NetworkCredential(service.ClientCredentials.UserName.UserName, service.ClientCredentials.UserName.Password);
    using (var handler = new HttpClientHandler { Credentials = creds })
    using (var client = new HttpClient(handler))
    {
        var uri = service.Endpoint.Address.Uri;
        var content = new FormUrlEncodedContent(new Dictionary<string, string>
        {
            {"Action", action},
            {"objectType", objectType.ToString()},
            {"sessionId", sessionId.ToString()},
            {"projectId", projectId.ToString()},
            {"batchId", batchId.ToString()},
            {"parentId", parentId.ToString()},
            {"objectId", objectId.ToString()},
            {"version", version.ToString()},
            {"streamName", streamName},
        });
        return await client.PostAsync(uri.OriginalString.Replace("/API/v1/Soap", "/FileService/v1"), content);
    }
}
```

<div id="start-and-end-batch-processing">
  ## Démarrer et terminer le traitement par lots
</div>

```csharp theme={null}
// Démarrer le traitement du lot
service.ProcessBatch(sessionId, batchId);
Console.WriteLine("recognition task created, waiting ");
// Attendre la fin du traitement
var percentCompleted = 0;
while (percentCompleted < 100)
{
    Console.CursorLeft = 0;
    Console.Write(percentCompleted + "%");
    percentCompleted = service.GetBatchPercentCompleted(batchId);
    System.Threading.Thread.Sleep(500);
}
Console.CursorLeft = 0;
Console.WriteLine("complete...");
```

<div id="get-the-results-and-display-the-captured-data">
  ## Récupérer les résultats et afficher les données capturées
</div>

Pour chaque document, seuls trois champs sont affichés :

* **Adresse**
* **Prénom**
* **Nom**

```csharp theme={null}
// Récupérer les résultats
var documents = service.GetDocuments(sessionId, batchId);
if (documents == null) return;
// Noms XML requis pour l'analyse des résultats XML
var docs = XName.Get("Documents", "https://www.abbyy.com/FlexiCapture/Schemas/Export/FormData.xsd");
var banking = XName.Get("_Banking_eng", "https://www.abbyy.com/FlexiCapture/Schemas/Export/Banking_eng.xsd");
// Parcourir tous les résultats et les afficher à l'écran
foreach (var document in documents)
{
    if (document.Id == 0) continue;
    // Récupérer le fichier XML avec les données reconnues
    var attachedFile = service.LoadDocumentResult(sessionId, batchId, document.Id, "Result.xml");
    if (attachedFile.Bytes == null) continue;
    // Ouvrir les résultats en XML
    var xml = XDocument.Load(new MemoryStream(attachedFile.Bytes));
    var docsElement = xml.Element(docs); // Conteneur pour les données reconnues
    if (docsElement == null) continue;
    var result = docsElement.Element(banking);
    if (result == null) continue;
    // Récupérer les données requises
    var addressing = result.Element("_Addressing");
    var surname = result.Element("_Last_Name");
    var name = result.Element("_First_Name");
    // Afficher les données
    Console.WriteLine("- " +
        (addressing == null ? "" : addressing.Value) + " " +
        (name == null ? "" : name.Value) + " " +
        (surname == null ? "" : surname.Value)
    );
}
```

<div id="close-the-session">
  ## Fermer la session
</div>

```csharp theme={null}
service.DeleteBatch(sessionId, batchId);
service.CloseProject(sessionId, projectId);
service.CloseSession(sessionId);
```
