> ## 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 die manuelle Verarbeitung

> Anhand eines ABBYY FlexiCapture-API-Beispiels erfahren Sie, wie Sie eine benutzerdefinierte Service-Stufe hinzufügen, um Aufgaben zu prüfen, Dokumente anzunehmen oder abzulehnen und eine digitale Signatur anzuhängen.

Dieses Beispiel zeigt, wie Sie eine zusätzliche Stufe für die manuelle Datenverarbeitung erstellen können. Diese Stufe kann beispielsweise von der Sicherheitsabteilung Ihres Unternehmens genutzt werden, um den Versand von Dokumenten zu prüfen und zu bestätigen, die bestimmte Bedingungen für die weitere Verarbeitung erfüllen, und um Dokumente abzulehnen, die diese Bedingungen nicht erfüllen.

Jedem bestätigten Dokument wird eine Bytefolge beigefügt, die eine digitale Signatur imitiert.

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

Das Beispiel führt die folgenden Schritte aus:

* Konfiguriert die Verbindung
* Nimmt die Arbeit mit dem Projekt auf
* Ruft die Aufgabenliste ab und verarbeitet sie
* Verarbeitet jede Aufgabe in der Service-Stufe
* Lädt die Datei auf den Server hoch
* Schließt die Sitzung

<div id="run-the-example">
  ## Führen Sie das Beispiel aus
</div>

<Steps>
  <Step title="Öffnen Sie die Lösung in Visual Studio">
    Öffnen Sie `UserStageExample.sln` in Visual Studio 2013 oder in einer neueren Version.
  </Step>

  <Step title="Geben Sie die URL des Application Server ein">
    Geben Sie die URL des Application Server ein.
  </Step>

  <Step title="Wählen Sie einen Authentifizierungstyp aus">
    Wählen Sie einen Authentifizierungstyp aus.
  </Step>

  <Step title="Melden Sie sich an">
    Klicken Sie auf **Login**.
  </Step>
</Steps>

<div id="configure-the-connection">
  ## Connection konfigurieren
</div>

```csharp theme={null}
private const string FlexiHandlerPath = "/FlexiCapture12/Server/{0}API/v1/Soap"; // Pfad zur FlexiCapture API
private const string FlexiCaptureAuthPart = "FCAuth/"; // Pfad zur Authentifizierung bei FlexiCapture
private const string UserStageProjectName = "UserStageExample"; // Der Name des in diesem Beispiel verwendeten Projects
private const string UserStageName = "Service"; // Der Name der Service-Stufe
// Neue Bindung erstellen
var binding = new BasicHttpBinding();
// Die Nachrichtengröße ist für FlexiCapture zu klein und muss erhöht werden
binding.MaxReceivedMessageSize = MessageSize;
// Sicherheitsmodus der Verbindung je nach Protokoll auswählen
binding.Security.Mode = serverUri.Scheme == Uri.UriSchemeHttps
   ? BasicHttpSecurityMode.Transport
   : BasicHttpSecurityMode.TransportCredentialOnly;
// Authentifizierungsmethode auswählen
binding.Security.Transport.ClientCredentialType = windowsAuth
   ? HttpClientCredentialType.Windows
   : HttpClientCredentialType.Basic;
// Pfad zur API je nach Authentifizierungsmethode auswählen
var externalSuffix = windowsAuth ? string.Empty : FlexiCaptureAuthPart;
var remoteAddress = new EndpointAddress(new Uri(serverUri, string.Format(FlexiHandlerPath, externalSuffix)));
// SOAP-Client erstellen
_client = new FlexiCapture.FlexiCaptureWebServiceSoapClient(binding, remoteAddress);
// Zur Authentifizierung bei FlexiCapture Anmeldename und Kennwort angeben
if (_client.ClientCredentials != null && !windowsAuth)
{
   _client.ClientCredentials.UserName.UserName = login;
   _client.ClientCredentials.UserName.Password = password;
}
```

<div id="start-working-with-the-project">
  ## Mit dem Project arbeiten
</div>

```csharp theme={null}
// Sitzung öffnen
_sessionId = _client.OpenSession(RoleType, WorkstationType);
var projectGuid = string.Empty;
// Erforderliches Project suchen
foreach (var project in _client.GetProjects())
{
   if (project.Name == UserStageProjectName)
   {
      projectGuid = project.Guid;
   }
}
if (string.IsNullOrEmpty(projectGuid))
{
   MessageBox.Show("The server does not contain the UserStageExample project which is needed for this example");
}
// Project öffnen
_projectId = _client.OpenProject(_sessionId, projectGuid);
// Bezeichner der Service-Stufe suchen und speichern
var stages = _client.GetProcessingStages(_projectId, 0, 0, UserStageName);
if (stages.Count != 1) throw new Exception("Invalid project");
   _serviceStageId = stages[0].Id;
// Externe ID der Ausnahmestufe suchen und speichern
stages = _client.GetProcessingStages(_projectId, 0, ExceptionStageType, string.Empty);
if (stages.Count != 1) throw new Exception("Invalid project");
   _exceptionsStageId = stages[0].ExternalId;
```

<div id="get-and-process-tasks-pending-at-the-service-stage">
  ## Abrufen und Verarbeiten der in der Service-Stufe ausstehenden Aufgaben
</div>

```csharp theme={null}
// Aufgabenliste abrufen
var tasks = _client.GetAvailableTasksByStageId(_sessionId, _projectId,
new FlexiCapture.stageIds() { _serviceStageId }, false);
var result = new Dictionary<int, Task>();
if (tasks == null || tasks.Count == 0) return result;
foreach (var task in tasks)
{
   // Für jede Aufgabe wird ein Objekt vom Typ Task erstellt
   var item = new Task
   {
      Id = task.Id,
      BatchId = task.BatchId
   };
   // Dokumentenliste der Aufgabe abrufen
   var documents = _client.GetTaskDocuments(task.Id);
   if (documents == null || documents.Count == 0) continue;
   foreach (var document in documents)
   {
      // XML-Datei der Aufgabe laden
      var file = _client.LoadDocumentResult(_sessionId, document.BatchId, document.Id, "DocumentBody"); // "DocumentBody" – der Name der Datei, die die erkannten Daten enthält
      if (file == null || file.Bytes == null) continue;
      // XML-Datei zerlegen
      var doc = new Document(document.Id, XDocument.Load(new MemoryStream(file.Bytes)));
      // Zerlegte Dokumentenliste speichern
      item.Documents.Add(document.Id, doc);
   }
   result.Add(item.Id, item);
}
```

<div id="send-the-task-for-further-processing">
  ## Aufgabe zur weiteren Verarbeitung senden
</div>

```csharp theme={null}
var ids = new FlexiCapture.docIds();
foreach (var rejectedDocument in rejectedDocuments)
{
   ids.Add(rejectedDocument.Id);
}
if (ids.Count > 0)
{
   _client.CreateTask(_sessionId, batchId, _exceptionsStageId, 0, "Rejection reason", 0, ids, false);
}
_client.OpenBatch(_sessionId, batchId);
var hasDocuments = false;
try
{
   var uri = _client.Endpoint.Address.Uri.OriginalString.Replace("/API/v1/Soap", "/FileService/v1");
   foreach (var document in acceptedDocuments)
   {
      hasDocuments = true;
      var buffer = new byte[SignatureSize]; // Die Größe der digitalen Signatur, die den Dokumenten hinzugefügt wird: 1024
      _rng.GetBytes(buffer);
      //DocumentAttachment: Der Anlagentyp (9 – Dokumentanlage)
      _client.SaveAttachment(_sessionId, DocumentAttachment, document.Id, batchId, _projectId, new FlexiCapture.File
      {
         Bytes = buffer,
         Name = "Signature.dat"
      });
      document.CreateStamp();
      UploadTextFileToServer(new Uri(uri),
         _client.ClientCredentials.UserName.UserName,
         _client.ClientCredentials.UserName.Password,
         document.GetXml(), 0, _sessionId, _projectId,
         batchId, 0, document.Id, 0, "DocumentBody"
      ).Wait();
   }
};
```

<div id="upload-the-file-to-the-server">
  ## Datei auf den Server hochladen
</div>

```csharp theme={null}
private static async Task<string> UploadTextFileToServer(Uri server, string login, string password,
        string stream, int objectType, int sessionId, int projectId, int batchId, int parentId,
        int objectId, int version, string streamName)
{
        var creds = CredentialCache.DefaultNetworkCredentials;
        if (!string.IsNullOrEmpty(login)) creds = new NetworkCredential(login, password);
        using (var handler = new HttpClientHandler { Credentials = creds })
        using (var client = new HttpClient(handler))
        {
                var encodedStreamName = Convert.ToBase64String(Encoding.Unicode.GetBytes(streamName));
                var content = new MultipartFormDataContent
                {
                        {new StringContent("Save"), "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(encodedStreamName), "streamName"},
                        {new ByteArrayContent(Encoding.Unicode.GetBytes(stream)), "blob", "data.txt"}
                };
                var msg = client.PostAsync(server, content).Result;
                return await msg.Content.ReadAsStringAsync();
        }
}
```

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

```csharp theme={null}
_client.CloseProject(_sessionId, _projectId);
   _client.CloseSession(_sessionId);
```
