> ## 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.

# Beispiel für automatische Verarbeitung

> Anhand eines ABBYY FlexiCapture-API-Beispiels wird gezeigt, wie eine Sitzung geöffnet, ein Batch erstellt, Bilder von Kontoeröffnungsanträgen hochgeladen, diese verarbeitet und die Ergebnisse ausgelesen werden.

Dieses Beispiel zeigt, wie Anträge auf Kontoeröffnung auf den Server hochgeladen und die Kundendaten erfasst werden.

<div id="what-the-example-does">
  ## Was das Beispiel macht
</div>

Der Beispielcode führt die folgenden Schritte aus:

* Stellt eine Verbindung zum Service her
* Öffnet eine Sitzung
* Öffnet das Projekt
* Erstellt einen neuen Batch
* Fügt dem Batch Bilder hinzu
* Startet die Verarbeitung des Batches
* Ruft die Ergebnisse ab und zeigt die erfassten Daten an
* Schließt die Sitzung

<div id="set-up-the-example">
  ## Das Beispiel einrichten
</div>

<Steps>
  <Step title="Die Projektdatei auf den Server hochladen">
    Laden Sie die Projektdatei `UnattendedExample.fcproj` auf den Server hoch.
  </Step>

  <Step title="Die Lösung in Visual Studio öffnen">
    Öffnen Sie `UnattendedExample.sln` in Visual Studio 2013 oder neuer.
  </Step>
</Steps>

<div id="connect-to-the-service">
  ## Mit dem Service verbinden
</div>

```csharp theme={null}
// Eine Instanz des Webservice-Clients erstellen
var service = new FlexiCapture.FlexiCaptureWebServiceSoapClient();
// ======= BASIC-AUTHENTIFIZIERUNG =======
// service.ClientCredentials.UserName.UserName = "username";
// service.ClientCredentials.UserName.Password = "password";
```

<div id="open-a-session">
  ## Eine Sitzung öffnen
</div>

```csharp theme={null}
// Um Ihre Batches vor unbefugtem Zugriff zu schützen, geben Sie den aktuellen Benutzer an
// Rufen Sie zunächst den für das System sichtbaren Benutzernamen ab
var username = service.GetCurrentUserIdentity();
// Suchen Sie sich anschließend in der Liste der FlexiCapture-Benutzer
var userId = service.FindUser(username.Name);
if (userId <= 0) throw new Exception("Current user not found");
// Öffnen Sie eine neue Verarbeitungssitzung
const int roleType = 12; //Die Operator-Rolle auf der Station des Benutzers
const int stationType = 10; //Die Station des Benutzers
var sessionId = service.OpenSession(roleType, stationType);
if (sessionId <= 0) throw new Exception("Couldn't open the session");
```

<div id="open-the-project">
  ## Projekt öffnen
</div>

```csharp theme={null}
// Projekte abrufen
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.");
}
// Erstes Projekt mit dem Namen UnattendedExample öffnen
var projectId = service.OpenProject(sessionId, projectGuid);
if (projectId <= 0) throw new Exception("Couldn't open the project");
```

<div id="create-a-new-batch">
  ## Neuen Batch erstellen
</div>

```csharp theme={null}
// Namen für den neuen Batch angeben und die anderen Eigenschaften unverändert lassen
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">
  ## Bilder zum Batch hinzufügen
</div>

```csharp theme={null}
// Batch öffnen, um Bilder hinzuzufügen
service.OpenBatch(sessionId, batchId);
```

<div id="upload-files-smaller-than-256-kb">
  ### Hochladen von Dateien unter 256 KB
</div>

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

<div id="upload-larger-files">
  ### Hochladen größerer Dateien
</div>

Das vollständige Hochladen von Dateien mit mehr als 256 KB als Base64 hat folgende Nachteile:

* Die Netzwerkauslastung steigt um 33 %.
* Sehr große Anfragen können von IIS oder der Firewall blockiert werden.
* Wenn die Verbindung unterbrochen wird oder Netzwerkfehler auftreten, müssen Sie die Datei erneut senden.

Das Hochladen von Dateien über die File-Service-API ist deutlich effizienter:

```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">
  #### Hochladen einer Datei auf den Server
</div>

Die `UploadFile`-Methode liest die Datei und sendet sie in 1-MB-Blöcken an den File-Service; anschließend verifiziert sie den Upload anhand einer Prüfsumme:

```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))
    {
        // Hochladen der Datei in Blöcken von 1 MB
        var buffer = new byte[0x100000];
        var readed = fs.Read(buffer, 0, buffer.Length);
        var checksum = crc.Next(buffer, 0, readed);
        if (readed < buffer.Length)
        {
            // Kleinere Dateien vollständig hochladen
            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">
  #### Senden einer Dateianfrage mit Dateiinhalt
</div>

Die `FileRequest`-Methode hat zwei Überladungen, die eine Aktion an den File-Service senden. Die erste sendet den Dateiinhalt als Multipart-Formulardaten:

```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">
  #### Eine Dateianforderung ohne Dateiinhalt senden
</div>

Die zweite Überladung sendet eine Anforderung ohne Dateiinhalt und verwendet dabei URL-Formularkodierung:

```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">
  ## Batch-Verarbeitung starten und beenden
</div>

```csharp theme={null}
// Batch-Verarbeitung starten
service.ProcessBatch(sessionId, batchId);
Console.WriteLine("recognition task created, waiting ");
// Warten, bis die Verarbeitung abgeschlossen ist
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">
  ## Ergebnisse abrufen und erfasste Daten anzeigen
</div>

Aus jedem Dokument werden nur drei Felder angezeigt:

* **Anschrift**
* **Vorname**
* **Nachname**

```csharp theme={null}
// Ergebnisse abrufen
var documents = service.GetDocuments(sessionId, batchId);
if (documents == null) return;
// XML-Namen zum Parsen der XML-Ergebnisse erforderlich
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");
// Alle Ergebnisse durchlaufen und auf dem Bildschirm anzeigen
foreach (var document in documents)
{
    if (document.Id == 0) continue;
    // XML-Datei mit den erkannten Daten abrufen
    var attachedFile = service.LoadDocumentResult(sessionId, batchId, document.Id, "Result.xml");
    if (attachedFile.Bytes == null) continue;
    // Ergebnisse als XML öffnen
    var xml = XDocument.Load(new MemoryStream(attachedFile.Bytes));
    var docsElement = xml.Element(docs); // Container für erkannte Daten
    if (docsElement == null) continue;
    var result = docsElement.Element(banking);
    if (result == null) continue;
    // Erforderliche Daten abrufen
    var addressing = result.Element("_Addressing");
    var surname = result.Element("_Last_Name");
    var name = result.Element("_First_Name");
    // Daten anzeigen
    Console.WriteLine("- " +
        (addressing == null ? "" : addressing.Value) + " " +
        (name == null ? "" : name.Value) + " " +
        (surname == null ? "" : surname.Value)
    );
}
```

<div id="close-the-session">
  ## Sitzung schließen
</div>

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