pitFM Add-on - Microsoft Graph (pitFM_MsGraphClient.dll)
Dieses Add-on bietet Zugriff auf die Microsoft Graph API. Folgende Features sind enthalten:
- Empfangen/Lesen von E-Mails
- Erstellen/Senden von E-Mails
- Verschieben von E-Mails
Entity(Staging)-Features:
- Empfangen/Lesen von E-Mails
- Erstellen/Senden von E-Mails
- Abrufen aller E-Mail-Verzeichnisnamen
- Abrufen aller Kontakt-Verzeichnisnamen
- Erstellen von E-Mail-Verzeichnisnamen
- Erstellen von Kontakt-Verzeichnisnamen
- Exportieren von Kontakten von pit nach MS Graph
- Erstellen, Aktualisieren und Löschen einzelner Kontakte
- Erstellen und Aktualisieren von Terminen
Technisches
Code-Respository: https://dev.azure.com/pit-cup/pitFM_Addons/_git/pitFM_MsGraphClient
Releaseverzeichnis: X:\FM\AddOns\MsGraphClient pitftp.de/pitFM_AddOns/MsGraphClient
Dieses Add-on wird vorerst als Merged-DLL geliefert, da pit erst ab Version 27 die Unterverzeichnisse für Add-ons unterstützt. Im AppConfig-Branch wird der Stand gehalten, mit welchem keine Merged-DLL erstellt wird. Dafür wird die AppConfig mit den Binding-Redirects erzeugt welche in die pitfm.exe.config übernommen werden können.
Info zum Common-Namespace
Alles, was unter Common liegt, soll ggf. mal in eine allgemeine pit-Bibliothek ausgelagert werden, da es in mehreren Addons benötigt wird. Hier ist es aktuell das Logging, was ggf. herausgelöst werden soll.
Logging
Ebene | Aufgabe | Welche Logs? | Log-Level |
---|---|---|---|
Adapter | Direkte Kommunikation mit der API | - Request-Daten (ohne sensible Infos) - Response-Statuscodes - Fehler (Timeouts, Bad Requests, Server Errors) |
Info (Erfolgreiche Requests) Warning (Fehlerhafte Antworten) Error (Timeouts, unerwartete Fehler) |
Service | Geschäftslogik und Fehlerhandling | - Wichtige Aktionen in der App - Ob API-Call erfolgreich war oder eine andere Strategie nötig ist - Kontext der API-Nutzung (Warum wird der Call gemacht?) |
Info (Erfolgreiche Verarbeitung) Warning (Fehlversuche mit Fallback-Strategie) Error (Wenn API-Fehler die Funktionalität beeinträchtigen) |
WICHTIG
Folgendes muss beachtet werden, wenn pitFM nicht als strong named Variante verwendet wird. Die CliDefines.dll im pit-bin-Verzeichnis muss durch die strong named Variante ersetzt werden. Die notwendige strong named CliDefines.dll ist unter X:\FM\AddOns_CliDefines_strong_named (pitftp.de/pitFM_AddOns/_CliDefines_strong_named) zu finden. Diese ist kompatibel mit pitFM v21 - v26.
Technisches zur Verwendung von Pit Entities
Beim Abrufen von PitAttributen muss "MsGraph_" vor den Attributname gehängt werden. Dieser Präfix ist in der Klassen-Property AttributeNames.PrefixName verfügbar.
Berechtigung für das Addon bestätigen
Die Berechtigungen für das Addon müssen bestätigt werden, wenn mittels UserLogin gearbeitet wird. Also wenn MsGraphClientInitializeViaUserLogin() verwendet wird.
Folgende URL muss erzeugt und im Browser ausgeführt werden. Es ist die {TENANT_ID} und die {CLIENT_ID} inklusive der geschweiften {} zu ersetzen. Das letzte Argument, der Scope ist die Berechtigung. Hier in dem Beispiel "User.Read".
Nach dem Aufruf der URL im Browser muss man sich mit den Logindaten aus dem MsGraphClient-Addon einloggen. Nach dem Login wird ein Bestätigungsdialog angezeigt, in welchem man alle angefragten Berechtigungen aufgelistet bekommt. Die Berechtigungen müssen bestätigt werden. Danach funktioniert das Addon mit diesen Logindaten.
https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/authorize?client_id={CLIENT_ID}&response_type=code&scope=User.Read
Wenn die Methode MsGraphClientInitializeViaUserLogin verwendet wird, müssen folgende Berechtigungen gesetzt sein.
Am besten die folgende URL nutzen und Tenant, sowie ClientId anpassen.
ACHTUNG: Wenn eine Berechtigung nicht gegeben wurde, funktioniert der GraphClient nicht. Bis auf die Shared-Berechtigungen müssen alle, in der Liste aufgeführten, Berechtigungen gegeben werden.
https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/authorize?client_id={CLIENT_ID}&response_type=code&scope=User.Read%20Mail.ReadWrite%20Mail.Send%20Calendars.ReadWrite%20Contacts.ReadWrite
Es können mehrere Berechtigungen mit einem mal bestätigt werden. Dazu müssen die Berechtigungen mittels %20 getrennt als Parameterwert übergeben werden. Im folgenden Beispiel werden "User.Read", "Mail.ReadWrite" und "Mail.Send" übergeben.
&scope=User.Read%20Mail.ReadWrite%20Mail.Send
Sonderfall shared Mailboxen (Postfächer)
Shared Mailboxen sind ein Sonderfall, wenn die Authentifizierung mittels UserCredentials durchgeführt wird.
Der User muss die Berechtigungen für "User.Read", "Mail.ReadWrite.Shared" und "Mail.Send.Shared" bewilligt haben. Sonst sind keine weiteren Berechtigungen nötig.
Wenn der User die shared Mailbox bei der Authentifizierung angibt, kann er nur E-Mail-Operationen auf dieser shared Mailbox ausführen.
Er hat keinen Zugriff auf seine persönliche Mailbox und darin enthaltene Termine oder Kontakte. Dazu muss er sich ohne Angabe der shared Mailbox authentifizieren.
Bei der Authentifizierung mittels Client-Secret gibt es keine Shared Mailboxen im allgemeinen Sinn. Denn jeder Mailbox-Zugriff ist ein shared Zugriff und benötigt vom Admin gesetzte Berechtigungen.
Aktuell benötigte Berechtigungen
Berechtigung | Login-Mechanismus | Weitere Informationen |
---|---|---|
User.Read | Delegiert / via User-Login | ab V1.2.0 notwendig |
Mail.ReadWrite | Delegiert / via User-Login | ab V1.2.0 notwendig |
Mail.Send | Delegiert / via User-Login | ab V1.2.0 notwendig |
Mail.ReadWrite.Shared | Delegiert / via User-Login | ab V2.0.0 notwendig - E-Mail-Entwürfe lesen/erstellen/bearbeiten |
Mail.Send.Shared | Delegiert / via User-Login | ab V2.0.0 notwendig - E-Mail-Entwürfe versenden |
Calendars.ReadWrite | Delegiert / via User-Login | ab V2.0.0 notwendig |
Contacts.ReadWrite | Delegiert / via User-Login | ab V2.0.0 notwendig |
- | - | |
User.Read.All | Anwendung / via Client-Secret | |
Mail.ReadWrite | Anwendung / via Client-Secret | |
Mail.Send | Anwendung / via Client-Secret | |
Calendars.ReadBasic | Anwendung / via Client-Secret | Termine abrufen, Verfügbarkeit: Minimal-Berechtigung für Kalenderzugriff auf andere Ressourcen. Es wird nur Start-/Endzeit vom Termin sowie Status angezeigt. Betreff und Inhalt sind leer. |
(Calendars.Read) | Anwendung / via Client-Secret | Termine abrufen, Verfügbarkeit: Vollen Lese-Zugriff auf alle Kalender im Tenant. |
Calendars.ReadWrite | Anwendung / via Client-Secret | Termin erstellen und aktualisieren |
Contacts.ReadWrite | Anwendung / via Client-Secret | Kontakte erstellen und aktualisieren |
Konvertierung von Datum
Das Addon geht bei einem Datum aus pitFM heraus immer von einem lokalen Datum aus. Also ein Datum in der aktuellen Zeitzone.
In MS Graph wird intern mit UTC gearbeitet. Dadurch ergeben sich Sonderfälle.
Beim Verwenden des Addons muss man sich nicht um die Konvertierung der Uhrzeit kümmern. Dies wird vom Addon übernommen.
Die aufgeführten Sonderfälle sind jedoch zu beachten.
- Jedes Datum von Ms Graph ist UTC.
- Das empfangene Datum wird in die lokale Zeit konvertiert und an pit übergeben.
- Jedes Datum welches das Addon an Ms Graph sendet, wird von Lokal in UTC konvertiert.
- Sonderfall - Termine
- Für Termine gibt es einen eigenen Datentyp.
- Jedes Termin-Datum welches nach Ms Graph übertragen wird, wird automatisch mit den Zeitzoneninformationen übergeben.
- Diese Zeitzoneninformationen werden von dem Rechner ermittelt, auf welchem des pit-FM läuft.
- Diese Zeitzoneninformationen können über die Methode SetTimeZone überschrieben werden.
Release Notes
Version 2.x.0 - alpha
- Entity Support -> Funktionen beginnen mit MsGraphEntityClient[SendMessages]
- Es werden Staging-Klassen im pitFM erstellt. (für E-Mail abrufen und senden)
- In diesen Klassen werden Entitys abgelegt. (abgerufene/gesendete E-Mails)
- ID nach dem Mail senden zurück in das pitSendEntity zurückspielen
- Referenzierte Attributdefinition mit nullable/notNullable setzen
- Logging vereinheitlichen
- Attachment-Unterstützung bei den Entities
- Angabe des Speicherorts beim Laden der Attachments für Message-Entities
- Gesendete E-Mails können gelöscht werden.
- E-Mail-Folders als Entity abrufen. Es wird der Name, die GraphId und der ParentFolder gespeichert.
- Contact-Folders als Entity abrufen. Es wird der Name, die GraphId und der ParentFolder gespeichert.
- Termine als Entity abrufen/aktualisieren
- Termine aus dem Entity heraus erstellen/aktualisieren
- Mailbox als Referenz-Klasse für Termine zur Verfügung gestellt. Das sind die Teilnehmer-E-Mails.
- Durch Referenzierung von CliModel.dll wird das Addon nun als Strong Named und nicht Strong Named zur Verfügung gestellt.
- BreakingChange in Methode MsGraphClientMailAddAttachment erzeugt. Name des Attachments fällt weg.
- SharedMailbox Support für Authentifizierung über user + passwort.
- Alle notwendigen Entities für MsGraph besitzen ein OriginMailbox-Feld durch welches ersichtlich ist, aus welchem Postfach dieses Entity stammt.
Version 1.2.1
- Addon auf basis von .Net-Framework 4.7.2 (TLS 1.2)
- E-Mails erstellen und versenden wurde für pit-WT Thread-Safe gemacht.
Version 1.2.0
- Methode zum Abrufen von E-Mails ohne Anhang und ohne Inlinebilder erstellt.
- Alle Log-Nachrichten werden jetzt über Trace.TraceInformation geloggt.
- Auf .Net-Framework 4.8.1 erhöht um HTTP-Verbindungen mit TLS 1.3 zu ermöglichen.
- Deadlocks, die in manchen pitFM-Projekten auftraten, gefixt.
- Beim Abrufen der E-Mails mittels MsGraphClientReadMessages() kann die maximale Anzahl angegeben werden.
- Bibliotheken Microsoft.Graph und MimeKit aktualisiert.
- Auf CliDefines.dll ohne strong name umgestellt um die Kompatibilität mit pitFM ohne strong name besser zu unterstützen.
Version 1.1.1
- Für die Requests kann jetzt ein Timeout gesetzt werden. Standard ist 120 Sekunden.
- Fix: Die Proxykonfiguration wird auf den GraphClient angewendet.
Version 1.1.0
- Addon wurde in pitFM_MsGraphClient umbenannt.
- E-Mails versenden inkl. Attachments. Inlinebilder als Attachments versenden wird nicht unterstützt.
- Inlinebilder, welche im HTML-Content der E-Mail eingebettet sind, können versendet werden.
- Das Add-on unterstützt auch Proxy's.
- Bei Nutzung von MsGraphClientInitializeViaUserLogin() muss der Nutzer die Berechtigung "Mail.Send" für das Addon bestätigen.
Version 1.0.4
- Inlinebilder werden als Attachments verfügbar gemacht.
Version 1.0.3
- Die CliDefines wird unterstützt. Dadurch unterstützen die Pit-Funktionen das FctExport-Attribut.
Version 1.0.2
- Das Logging/Tracing des Add-ons kann aktiviert und ein Log-Level definiert werden.
- Das Error-Handling der pit-Methoden vervollständigt.
Version 1.0.1
- Add-on wird als Merged-DLL geliefert
Version 1.0.0
- Das Abfragen von E-Mails über MS Graph API ist implementiert.
- Authentifizierung mittels Client-Secret und User-Login möglich.
- E-Mails aus einem Postfach-Verzeichnis abrufen.
- Gelesen-Status der E-Mail setzen.
- Löschen der E-Mail verschiebt diese in den Ordner "Gelöschte Nachrichten".
- Das Abrufen und Ablegen der E-Mail-Anhänge ist implementiert.
- E-Mail-Anhänge werden mit gültigen Dateinamen im lokalen Dateisystem abgelegt. Ungültige Sonderzeichen werden aus dem Dateinamen entfernt.
- Jede E-Mail bekommt im User-Temp ein separates Verzeichnis, falls dafür Anhänge abgelegt werden müssen.
Offene Punkte
E-Mails mit Filter nach gelesen/ungelesen abrufen. Ist implementiert aber noch nicht im Add-On verfügbar, da nur das neuste pit nullable-Types unterstützt.
Aktuell werden nur Attachments welche eine Datei oder eine E-Mail-Nachricht sind unterstützt und an pit übergeben. Es wird sich mit den kommenden Projekten zeigen, ob wir weitere Arten von Anhängen unterstützen müssen.
Impersonation auch bei login mit Nutzerdaten unterstützen. (gibt es nicht in MS Graph) -> senden/lesen über/aus shared mailbox
Login via JSON-WEB-TOKEN (JWT) -> Der OAuth2 Access Token ist ein JSON-Web-Token
- OAuth2 funktioniert nicht im ServiceMode, da ein Login-WebDialog angezeigt wird für die erste Anmeldung und wenn der Refresh-Token abgelaufen ist.
- Außerdem muss die Redirect-URI in AzureAD registriert sein. Über diese kommt der AccessToken und RefreshToken.
- RefreshToken muss von pit oder dem Add-on gespeichert werden. Ablaufdauer wird in Azure eingestellt und kann also von Projekt zu Projekt variieren.
- Wenn man den Refresh-Token besitzt und dieser nicht abgelaufen ist kann der AccessToken auch silent aktualisiert werden.
- ServiceMode ohne Anmeldung durch Nutzer ist nur mit ClientSecret bzw. Zertifikat möglich.
- Benötigt Admin-Zustimmung für Berechtigungen wie Mail.Read.All
- OAuth2 funktioniert nicht im ServiceMode, da ein Login-WebDialog angezeigt wird für die erste Anmeldung und wenn der Refresh-Token abgelaufen ist.
Client soll auch mit OnPrem funktionieren (EWS)
Abrufen von Metadaten zu einer E-Mail: Definieren welche Felder abgerufen werden sollen (hole Subject, From): GET https://graph.microsoft.com/v1.0/me/messages?$select=subject,from
(Filtern von E-Mails nach verschiedenen Feldern (ungelesen, Absender)): GET https://graph.microsoft.com/v1.0/me/messages?$filter=isRead eq false and from/emailAddress/address eq 'info@pit.de'
- Für welchen Zweck? passiert das nicht auf den Items welche bereits in pit liegen?
- mögliche Lösung: Der Filter sollte vom Anpassungsentwickler erstellt und als vollständiger/valider String übergeben werden.
Verfügbarkeitsstatus einer Ressource zu einem zukünftigen Zeitpunkt für das Erstellen/Planen von Terminen. Dieser Status wird aus dem Kalender der Ressource ermittelt.
- Request: POST /users/{resourceId}/calendar/getSchedule
- Bsp. für {resourceId}: "alice@example.com", "meetingroom1@example.com", cfb93e71-33c4-4432-b0b2-123456789abc
- Die Frei/Gebucht-Zeitanzeige muss öffentlich oder für den Anfragenden freigegeben sein.
- Alternativ werden die Berechtigungen benötigt: Calendars.Read, Calendars.Read.Shared
Adressdaten nach MsGraph exportieren: pit-Address-Entity definieren welches in MsGraph exportiert werden kann
- Der Zielordner wird als ID angegeben. Es muss noch validiert werden, wie ein pfad übergeben werden muss.
Termine erstellen, laden, löschen, versenden (auch Serien-Termine)
Gemeinsamen Termin finden: POST https://graph.microsoft.com/v1.0/me/findMeetingTimes
- Achtung: Bei Terminfindung innerhalb einer Woche, muss für jeden Tag der Zeitraum definiert werden, da sonst auch ein Termin im Feierabend rauskommen kann
Termine für Person inkl Zeitraum abrufen: GET /users/{userId|email}/calendarView?startDateTime=2025-05-13T00:00:00&endDateTime=2025-05-17T23:59:59
Ressourcen-Kalender abrufen
?Welche Unterstützung bei Serienterminen ist gemeint?
Termine importieren um diese darzustellen
(Proxyklassen) Datenstruktur in pit definieren/liefern und aus addon befüllen
- evtl. nur beim Import
Synchronisation von Adressdaten(email, Daten in Outlook) Create / Update / Delete -> von pit in den Outlook-Ordner
Exchange-Addon (Ralf Dömke sein Addon)
Weitere Features
- OneDrive, SharePoint, Teams
Fragen zu Anforderungen:
Approvements
- Mit SendMessageEntity Attachments versenden.
- Impersonation (gibt es nicht in MS Graph) -> senden/lesen über/aus shared mailbox
- Nach MsGraphClientGetMessage() müssen die Attachments wieder aus dem Speicher entfernt werden.
- Appointments abrufen
- Verfügbarkeit abrufen
- freies Zeitfenster ermitteln
- Appointments bearbeiten / erstellen
- Zeitzonen-Konvertierung einbauen
- Tests für Appointment-Konvertierung erstellen
- Vorschlagswerte an Attributdefinition hängen.
- Nur Vorschlagswerte zulassen aktivieren.
- Parent-Folders sollen als Referenzen erstellt werden.
TODOs
- ✅☑️ Pagination bei Emails (Funktion+Entity)
- ✅☑️ E-Mail-Abruf mit Filter (Funktion+Entity)
- ✅☑️ E-Mail-Abruf mit Feldselektion (Funktion+Entity)
- ☑️ E-Mail verschieben auf absoluten Pfad umstellen
- ✅☑️ Abrufen der E-Mails mit absolutem Pfad
- Email verschieben auch für Entity verfügbar machen. (Property für Folder) -? den neuen Path über Funktionsparameter übergeben -> Danach Path und ParentFolderId aktualisieren -? die neuen ParentFolderId über Funktionsparameter übergeben -> Danach Path und ParentFolderId aktualisieren -? die neuen ParentFolderId im Entity setzen und EntityMove Methode mit EntityData ausführen -> Danach Path und ParentFolderId aktualisieren
- ✅ E-Mails beim Abrufen mit Pfad versehen
- ✅ Kontakte beim Abrufen mit Pfad versehen
- ☑️ E-Mail Folders mittels absoluten Pfad erstellen (Funktion)
- ☑️ Kontakt Folders mittels absoluten Pfad erstellen (Funktion)
- ✅ Kontakte exportieren (
Funktion+Entity) - ✅ Kontakt-Entities sollen der pit-Entity-exportieren-Methode übergeben werden
- ✅ virtuelle Entities dafür nutzen (Virtuelles entity wird durch setzen der Attribute auf nicht speichern erreicht.)
- ✅ GraphId und ParentGraphId zurück in ContactEntity schreiben
- ✅ Kontakte in MsGraph aktualisieren, wenn GraphId vorhanden ist (Entity)
- ✅☑️ Kontakte in MsGraph löschen
und verschiebenmit GraphId (Funktion+Entity) - 🆗 Projekt fachlich strukturieren.
- 🆗 (ReadyToSend für Entities wird entfernt und es wird eine gefilterte EntityListe der Methode übergeben)
- ✅ Termine sollen Attachments unterstützen.
- ✅☑️ Large-File-Upload support für E-Mail umsetzen
- ✅ Termine erstellen/aktualisieren umsetzen (Entity)
- ✅☑️ Refactoring: Attachment support für E-Mails empfangen
- 🆗 Versuchen das Addon Thread-safe zu machen.
- 🆗 FctExport flags korrigieren, -> const ...
- 🆗 Shared Mailbox unterstützen senden / empfangen
- 🆗 Tests für Shared Mailbox erstellen
- ✅ Postfach für die Entity-Elemente mit abspeichern. Die notwendigen Klassen erhalten das Textfeld OriginMailbox
- 🆗 Termine abrufen soll versteckt werden.
- 🆗 Serientermin Funktionalität vorerst nicht realisieren.
- 🆗 Alle Static-Member in eine Wrapper-Implementierung überführen.
- 🆗 Summarys in FktExport-Description und README übertragen
- Logging-Ausgaben überprüfen
- TestCoverage prüfen und sinnvoll Tests ergänzen
- Entities effizient abfragen. Siehe BuildAppointmentAdapters wo Appointments auch Mailboxes referenzieren.
- Definierte Vorschlagswerte (PitAttributeDefinitionSuggestedValue) aus den Models müssen an Attributdefinition angehangen werden
- Prüfen: Eigene Felder in die Assembly einbringen wo mindestversion von CliModel enthalten ist.
- sind die Felder sichtbar? Man kann nur in AssemblyMetadata schreiben. Diese Einträge sind leider nicht in den Dateieigenschaften sichtbar.
- Kann also nur in eines der Standardfelder eingetragen werden.
Next Steps
- Senden evtl. mit virtueller Klasse arbeiten
- Anforderungen in den GraphClient implementieren. Dann kann mittels Unittest geprüft werden ob die benötigten Daten verfügbar sind.
Für Entwickler
Die MS Graph REST API v1.0 ist unter https://learn.microsoft.com/de-de/graph/api/overview?view=graph-rest-1.0&preserve-view=true erreichbar. Es gibt von MS einen Graph-Explorer mit welchem die Requests getestet werden können. Es können Berechtigungen eingesehen und freigegeben werden. Es können die Responses zu den Requests geprüft werden.
Mögliche Exceptions
Wenn Exceptions auftreten werden diese im DebugView vollständig angezeigt.
unexpected exception=The specified object was not found in the store..
- Diese Exception tritt auf, wenn die GraphId eines Objektes nicht in MsGraph existiert und man diese zum Updaten des Objektes verwendet.
- Dies kann auch vorkommen, wenn man auf das Objekt über Postfach1 abgefragt hat und über Postfach2 versucht darauf zuzugreifen.
- Die MsGraphId ist immer nur innerhalb eines Postfaches gültig.
Funktionen
Logging de-/aktivieren
Das Logging wird mit dem Setzen eines gültigen Log-Levels aktiviert. Dann werden alle Meldungen in den Windows-Trace geschrieben. Diese Meldungen können mit einem TraceListener gelesen werden. Windows stellt mit DebugView ein Tool zur Verfügung, welches die Traces anzeigen und speichern kann. Gültige Log-Level sind der Summary unten zu entnehmen.
/// <summary>
/// Legt das globale Log-Level fest.
/// Wird das Log-Level auf einen ungültigen Wert gesetzt, wird das Logging deaktiviert.
/// </summary>
/// <param name="level">Das Log-Level: Trace=0, Debug=1, Info=2, Warning=3, Error=4, Fatal=5.</param>
public static void MsGraphClientSetLogLevel(int level)
Fehlerbehandlung
Wenn bei einer Funktion ein Fehler auftritt, wird dieser mit dem ReturnCode false angezeigt. Der Fehler kann danach mit folgenden Befehlen abgefragt werden.
/// <summary>
/// Liefert den letzten aufgetretenen Fehler zurück.
/// </summary>
/// <returns>Fehlermeldung als Text.</returns>
public static string MsGraphClientGetLastError()
Es kann auch eine Fehlerhistorie abgefragt werden. Diese enthält alle Fehler die seit der Initialisierung mit MsGraphClientInitializeViaClientSecret und MsGraphClientInitializeViaUserLogin aufgetreten sind.
/// <summary>
/// Liefert alle aufgetretenen Fehler seit der Initialisierung zurück.
/// </summary>
/// <returns>Die Fehlermeldungen sind zeilenweise enthalten. Trenner ist "\r\n".</returns>
public static string MsGraphClientGetErrorHistory()
E-Mails abrufen
E-Mails werden immer Ordnerbezogen abgerufen. Es muss beim Abrufen von E-Mails der Ordner mit seinem Namen angegeben werden, aus welchem die E-Mails abgerufen werden sollen. Wenn kein Ordername angegeben wird, wird der Posteingang als Ordner angenommen. Statt den Ordnernamen können auch die Ordner-Ids angegeben werden. Zur Information: Wenn der maxCount gesetzt wird und die Methode genau diese Anzahl an E-Mails abgerufen hat, ist es sehr wahrscheinlich dass noch mehr E-Mails im Postfach liegen.
/// <summary>
/// Ruft alle Nachrichten aus dem angegebenen E-Mailordner ab.
/// Wenn für <see cref="folderName"/> null übergeben wird, wird die Inbox/Posteingang als Standardorder gesetzt.
/// </summary>
/// <param name="folderName">Name/Id des E-Mailordners.</param>
/// <param name="maxCount">Die maximale Anzahl an E-Mails, welche abgerufen werden. Wenn nichts angegeben wird, werden 10 Stück abgerufen.</param>
/// <returns>Gibt die Anzahl der abgerufenen Nachrichten zurück.</returns>
public static int MsGraphClientReadMessages(string folderName, int maxCount = 0)
ACHTUNG: Bei der Angabe von Ordnernamen müssen die Standard-Ordner-Bezeichnungen verwendet werden. Siehe Tabelle unten. Da die Ordner in den Postfächern in ihrer gesetzten Ländersprache angezeigt werden. Bsp.: Der "Posteingang" in Deutsch heißt "Inbox" in Englisch und "Posta in arrivo" in Italienisch und kann nur mit dem Standardnamen "inbox" sprachübergreifend ermittelt werden.
Folgende Standardordner bietet die MS Graph-API an. Quelle
Standardname | Description |
---|---|
inbox | The inbox folder. |
outbox | The outbox folder. |
archive | The archive folder messages are sent to when using the One_Click Archive feature in Outlook clients that support it. Note: this isn't the same as the Archive Mailbox feature of Exchange online. |
sentitems | The sent items folder. |
deleteditems | The folder items are moved to when they're deleted. |
drafts | The folder that contains unsent messages. |
junkemail | The junk email folder. |
conflicts | The folder that contains conflicting items in the mailbox. |
conversationhistory | The folder where Skype saves IM conversations (if Skype is configured to do so). |
msgfolderroot | The "Top of Information Store" folder. This folder is the parent folder for folders that are displayed in normal mail clients, such as the inbox. |
scheduled | The folder that contains messages that are scheduled to reappear in the inbox using the Schedule feature in Outlook for iOS. |
searchfolders | The parent folder for all search folders defined in the user's mailbox. |
serverfailures | The folder that contains items that exist on the server but couldn't be synchronized to the local client. |
syncissues | The folder that contains synchronization logs created by Outlook. |
Eine E-Mail mit all seinen Daten abrufen
Um den Inhalt einer E-Mail in pit zu erhalten, müssen die E-Mails zuvor Ordnerbezogen abgerufen werden. Siehe E-Mails abrufen. Danach kann unter Angabe des Index die E-Mail mit seinem gesamten Inhalt aus pit abgefragt werden.
/// <summary>
/// Ruft die Daten einer E-Mail mittels Index ab und schreibt die Werte in die Parameter.
/// Falls diese E-Mail Anhänge besitzt werden diese vom Server geladen und lokal abgelegt.
/// Sonderfall Inline-Images: Inline-Images werden immer vom Server geladen. Die Images werden entweder in den Mail-Body
/// direkt eingebettet oder wie eine Attachment Datei übergeben. Wird über <paramref name="embedInlineImages"/> gesteuert.
/// Zuvor muss <see cref="MsGraphClientReadMessages"/> gerufen werden um die E-Mails abzurufen.
/// Index muss gültig sein.
/// </summary>
/// <param name="index">Der Index der Mail.</param>
/// <param name="embedInlineImages">Bei true werden Inline-Images direkt in den Mail-Body eingebettet.
/// Bei false werden die Dateinamen in die Inline-Images des Mail-Bodys geschrieben. Die Dateien sind dann über
/// <paramref name="inlineImages"/> zu bekommen.</param>
/// <param name="mailId">Die eindeutige Id der Mail.</param>
/// <param name="from">Die Mailadresse des Versenders.</param>
/// <param name="to">Die Mailadressen der Empfänger. Semikolon separierter String.</param>
/// <param name="cc">Die Mailadressen der CC-Empfänger. Semikolon separierter String.</param>
/// <param name="bcc">Die Mailadressen der BCC-Empfänger. Semikolon separierter String.</param>
/// <param name="attachments">Die Dateipfade zu den lokal gespeicherten Anhängen. Semikolon separierter String.</param>
/// <param name="subject">Das Mail-Subject.</param>
/// <param name="bodyType">Der Body-Type.</param>
/// <param name="bodyContent">Der Inhalt des Bodys.</param>
/// <param name="inlineImages">Dieses Feld ist nur gefüllt, wenn <paramref name="embedInlineImages"/>=false gesetzt ist.
/// Dann sind alle Inline-Images mit ihrem Dateipfad enthalten. Semikolon separierter String.</param>
/// <param name="receivedTime">Das Datum wann die Mail empfangen wurde.</param>
/// <returns>Liefert true, wenn alles funktioniert hat und false bei einem Fehler.</returns>
public static bool MsGraphClientGetMessage(
int index,
bool embedInlineImages,
ref string mailId,
ref string from,
ref string to,
ref string cc,
ref string bcc,
ref string attachments,
ref string subject,
ref string bodyType,
ref string bodyContent,
ref string inlineImages,
ref DateTime receivedTime)
Attachments in der E-Mail
Bei der Abfrage der E-Mail werden alle Anhänge der E-Mail vom Server geladen und in dem lokalen User-Temp-Verzeichnis abgelegt. Wenn der Anhang eine E-Mail ist, wird dieser Anhang als MIME-Datei mit all seinen internen Anhängen in die Datei geschrieben. Die Datei wird mit der Erweiterung ".eml" geschrieben und kann mit Outlook geöffnet werden.
Eine E-Mail ohne Attachments und ohne Inlinebilder abrufen
Um den Inhalt einer E-Mail in pit zu erhalten, müssen die E-Mails zuvor Ordnerbezogen abgerufen werden. Siehe E-Mails abrufen. Danach kann unter Angabe des Index die E-Mail aus pit abgefragt werden. Es werden keine Anhänge und keine Inlinebilder geladen.
/// <summary>
/// Ruft die Daten einer E-Mail mittels Index ab und schreibt die Werte in die Parameter.
/// Es werden keine Anhänge und keine Inline-Images aufgelöst.
/// Zuvor muss <see cref="MsGraphClientReadMessages"/> gerufen werden um die E-Mails abzurufen.
/// Index muss gültig sein.
/// </summary>
/// <param name="index">Der Index der Mail.</param>
/// <param name="mailId">Die eindeutige Id der Mail.</param>
/// <param name="from">Die Mailadresse des Versenders.</param>
/// <param name="to">Die Mailadressen der Empfänger. Semikolon separierter String.</param>
/// <param name="cc">Die Mailadressen der CC-Empfänger. Semikolon separierter String.</param>
/// <param name="bcc">Die Mailadressen der BCC-Empfänger. Semikolon separierter String.</param>
/// <param name="subject">Das Mail-Subject.</param>
/// <param name="bodyType">Der Body-Type.</param>
/// <param name="bodyContent">Der Inhalt des Bodys.</param>
/// <param name="receivedTime">Das Datum wann die Mail empfangen wurde.</param>
/// <returns>Liefert true, wenn alles funktioniert hat und false bei einem Fehler.</returns>
public static bool MsGraphClientGetMessageWithoutAttachments(
int index,
ref string mailId,
ref string from,
ref string to,
ref string cc,
ref string bcc,
ref string subject,
ref string bodyType,
ref string bodyContent,
ref DateTime receivedTime)
E-Mail verschieben
E-Mails können in andere E-Mail-Ordner verschoben werden. Zum Verschieben muss der Index der E-Mail angegeben werden und der Name bzw. die Id des E-Mail-Ordners.
/// <summary>
/// Verschiebt die E-Mail in den angegebenen Ordner. Der Index der Nachricht muss angegeben werden.
/// </summary>
/// <param name="index">Der Index der Mail.</param>
/// <param name="targetFolderPath">Path/Id des Mail-Ordners.</param>
/// <returns>Liefert true, wenn alles funktioniert hat, und false bei einem Fehler.</returns>
public static bool MsGraphClientMoveMessage(int index, string targetFolderPath)
/// <summary>
/// Verschiebt die E-Mail in den angegebenen Ordner. Die MS Graph Id der E-Mail muss angegeben werden.
/// </summary>
/// <param name="graphId">Die MS Graph ID der E-Mail.</param>
/// <param name="targetFolderPath">Path/Id des Mail-Ordners.</param>
/// <returns>Liefert die neue ParentFolderId in welchen die E-Mail verschoben wurde. Im Fehlerfall wird ein leerer String geliefert.</returns>
public static string MsGraphClientMoveMessageById(string graphId, string targetFolderPath)
E-Mail löschen
E-Mails werden nicht gelöscht, sondern in den Mailordner "Gelöschte Elemente" verschoben. Dies ist Standardverhalten bei E-Mail-Clients.
/// <summary>
/// Verschiebt die E-Mail in den Ordner "Gelöschte Elemente".
/// </summary>
/// <param name="index">Der Index der Mail.</param>
/// <returns>Liefert true, wenn alles funktioniert und false bei einem Fehler.</returns>
public static bool MsGraphClientDeleteMessage(int index)
/// <summary>
/// Verschiebt die E-Mail in den Ordner "Gelöschte Elemente". Die MS Graph Id der E-Mail muss angegeben werden.
/// </summary>
/// <param name="graphId">Die MS Graph ID der E-Mail.</param>
/// <returns>Liefert true, wenn alles funktioniert hat und false bei einem Fehler.</returns>
public static bool MsGraphClientDeleteMessageById(string graphId)
E-Mail als gelesen oder ungelesen setzen
/// <summary>
/// Setzt den Gelesen-Status einer E-Mail.
/// </summary>
/// <param name="index">Der Index der Mail.</param>
/// <param name="isRead">Der zu setzende Gelesen-Status der Mail.</param>
/// <returns>Liefert true, wenn alles funktioniert hat und false bei einem Fehler.</returns>
public static bool MsGraphClientSetMessageReadState(int index, bool isRead)
Proxy-Server angeben
Der Proxy-Server muss vor der Initialisierung des Add-Ons angegeben werden.
/// <summary>
/// Erstellt die Proxykonfiguration.
/// Diese Funktion muss vor den Initialize-Funktionen <see cref="MsGraphClientInitializeViaClientSecret"/> bzw. <see cref="MsGraphClientInitializeViaUserLogin"/> aufgerufen werden.
/// </summary>
/// <param name="proxyAddress">Die Adresse des Proxyservers.</param>
/// <param name="username">Optional: Der UserName zur Authentifizierung am Proxy.</param>
/// <param name="password">Optional: Das Passwort zur Authentifizierung am Proxy.</param>
/// <param name="domain">Optional: Die Domäne, die diesen Anmeldeinformationen zugeordnet.</param>
/// <returns>Liefert true, wenn alles funktioniert hat.
/// Bei false wird der Proxy trotzdem gesetzt. Es muss dann jedoch nochmal die Initialisierung mit den Login-Informationen durchgeführt werden.</returns>
public static bool MsGraphClientDefineWebProxy(string proxyAddress, string username = null, string password = null, string domain = null)
Add-On initialisieren
Das Add-On muss vor der Nutzung mit den notwendigen Daten initialisiert werden.
/// <summary>
/// Initialisiert den GraphClient mittels ClientSecret.
/// </summary>
/// <param name="tenantId">Die Tenant-/Mandant-/Verzeichnis-ID.</param>
/// <param name="clientId">Die Client-/Anwendungs-/App-ID.</param>
/// <param name="clientSecret">Das Client-Secret.</param>
/// <param name="emailAddress">Die Mailbox von welcher die E-Mails abgerufen werden sollen.</param>
/// <param name="requestTimeoutInSeconds">Timeout für alle Requests in Sekunden. standard = 120s.</param>
/// <returns>Liefert true, wenn alles funktioniert hat und false bei einem Fehler.</returns>
public static bool MsGraphClientInitializeViaClientSecret(
string tenantId,
string clientId,
string clientSecret,
string emailAddress,
int requestTimeoutInSeconds = 0)
/// <summary>
/// Initialisiert den GraphClient mittels Nutzername und Passwort.
/// Wenn hier eine <paramref name="sharedMailbox"/> gesetzt wird, arbeitet das gesamte Add-on nur noch auf dieser Mailbox
/// und nicht auf dem Postfach des Nutzers. Dadurch sind nur noch Funktionalitäten für E-Mails verfügbar.
/// </summary>
/// <param name="tenantId">Die Tenant-/Mandant-/Verzeichnis-ID.</param>
/// <param name="clientId">Die Client-/Anwendungs-/App-ID.</param>
/// <param name="user">Der Nutzername bzw. die E-Mail-Adresse des Nutzers.</param>
/// <param name="password">Das Passwort zu dem Nutzeraccount.</param>
/// <param name="sharedMailbox">Setzt den GraphClient auf eine shared Mailbox.</param>
/// <param name="requestTimeoutInSeconds">Timeout für alle Requests in Sekunden. standard = 120s.</param>
/// <returns>Liefert true, wenn alles funktioniert hat und false bei einem Fehler.</returns>
public static bool MsGraphClientInitializeViaUserLogin(
string tenantId,
string clientId,
string user,
string password,
string sharedMailbox = null,
int requestTimeoutInSeconds = 0)
E-Mail erstellen und versenden
Eine neue E-Mail muss initialisiert werden. Mit der Initialisierung werden alle bisher gesetzten Werte gelöscht.
/// <summary>
/// Initialisiert ein Mailobjekt.
/// Dadurch wird das vorherige Mailobjekt ersetzt und die bisherigen Anhänge/Attachments entfernt.
/// Wenn die senderAddress eine andere E-Mail als das aktuelle Postfach ist, wird
/// die E-Mail über das Postfach von senderAddress versendet. Dies ist zum Senden über eine shared Mailbox gedacht.
/// </summary>
/// <param name="subject">Der Betreff der E-Mail.</param>
/// <param name="body">Der Inhalt der E-Mail.</param>
/// <param name="bodyTypeIsHtml">Die Inhaltsart: True ist HTML-Content, False ist TEXT-Content.</param>
/// <param name="senderAddress">Optional: Die E-Mail-Adresse des Absenders. SharedMailbox. Wird automatisch auf die aktuelle Mailbox gesetzt.</param>
/// <param name="senderDisplayname">Optional: Der Anzeigename des Absenders. Wird nur gesetzt wenn <paramref name="senderAddress"/> gesetzt ist.</param>
/// <returns>Liefert true, wenn alles funktioniert hat und false bei einem Fehler.</returns>
public static bool MsGraphClientMailInitialize(
string subject,
string body,
bool bodyTypeIsHtml,
string senderAddress = null,
string senderDisplayname = null)
/// <summary>
/// Eine Empfängerin hinzufügen.
/// </summary>
/// <param name="recipientType">Die Empfängerart: TO = 1, CC = 2, BCC = 3.</param>
/// <param name="displayName">Der Anzeigename des Kontakts.</param>
/// <param name="mailAddress">Die E-Mail-Adresse des Kontakts.</param>
/// <returns>Liefert true, wenn alles funktioniert hat und false bei einem Fehler.</returns>
public static bool MsGraphClientMailAddRecipient(int recipientType, string displayName, string mailAddress)
/// <summary>
/// Ein Anhang/Attachment hinzufügen.
/// </summary>
/// <param name="filePath">Vollständiger Dateipfad der Datei.</param>
/// <param name="inlineId">Die ID für ein Inline-Attachment.</param>
/// <param name="isInline">Legt fest, ob diese Datei als Inline-Content verwendet wird.</param>
/// <returns>Liefert true, wenn alles funktioniert hat und false bei einem Fehler.</returns>
public static bool MsGraphClientMailAddAttachment(string filePath, string inlineId, bool isInline)
/// <summary>
/// Versendet die konfigurierte E-Mail.
/// Wenn die konfigurierte E-Mail als From-Recipient eine andere E-Mail als das aktuelle Postfach gesetzt hat, wird
/// die E-Mail über das Postfach der angegebenen E-Mail versendet. Dies ist zum Senden über eine shared Mailbox gedacht.
/// </summary>
/// <returns>Liefert true, wenn alles funktioniert hat und false bei einem Fehler.</returns>
public static bool MsGraphClientMailSend()
Funktionen mit pit Entity-Klassen (Staging-Tabellen)
E-Mails abrufen
/// <summary>
/// Ruft alle Nachrichten aus dem angegebenen E-Mailordner ab und erzeugt Entities im pit.
/// Wenn die Entities bereits existieren, werden neue Werte in das Entity übertragen/aktualisiert.
/// Es werden keine Attachments geladen. Das Nachladen ist mit <see cref="MsGraphEntityClientLoadAttachments"/> möglich.
/// Wenn für <paramref name="folderPath"/> null übergeben wird, wird die Inbox/Posteingang als Standardorder gesetzt.
/// </summary>
/// <param name="folderPath">Pfad/Id des Mailordners. Der einfache Name funktioniert nur, wenn sich der Mailordner auf Root-Ebene befindet. Auf Root-Ebene liegt z.B. inbox, outbox und drafts.</param>
/// <param name="filter">Setzt den Filter zum Abrufen der Mails. https://learn.microsoft.com/en-us/graph/filter-query-parameter.</param>
/// <param name="selectFields">E-Mail-Felder, welche abgerufen werden sollen.</param>
/// <param name="maxCount">Die maximale Anzahl an E-Mails, welche abgerufen werden. Wenn nichts angegeben wird, werden 10 Stück abgerufen.</param>
/// <returns>Gibt die Anzahl der abgerufenen Nachrichten zurück. Im Fehlerfall wird -1 zurückgegeben.</returns>
public static int MsGraphEntityClientReadMessages(string folderPath, string filter = null, string[] selectFields = null, int maxCount = 0)
/// <summary>
/// Ruft die nächsten Nachrichten aus dem voran gegangenen <see cref="MsGraphEntityClientReadMessages"/> Aufruf ab.
/// Hier wird mittels pagination der nächste Satz Nachrichten abgerufen.
/// Diese Methode muss so lange gerufen werden bis die Rückgabe 0 ist. Dann ist das Request mit seiner Pagination abgeschlossen.
/// ACHTUNG: Wenn zwischendurch <see cref="MsGraphEntityClientReadMessages"/> gerufen wird, wird die Pagination auf den neuen Request umgeswitcht.
/// </summary>
/// <returns>Liefert die Anzahl der abgerufenen Nachrichten zurück. Im Fehlerfall wird -1 zurückgegeben.</returns>
public static int MsGraphEntityClientReadNextMessages()
/// <summary>
/// Lädt die Dateianhänge für die E-Mail nach.
/// Falls die E-Mail eingebettete Bilder enthält, werden diese mit geladen und entweder eingebettet oder wie ein Dateianhang geliefert.
/// </summary>
/// <param name="entity">Das Message-Entity.</param>
/// <param name="embedInlineImages">True: Inline-Bilder in die Mail integrieren. False: Bilder als Anhang laden.</param>
/// <param name="downloadPath">
/// Optional: Der Downloadpfad, in welchem das E-Mail-Verzeichnis erstellt und die Attachments heruntergeladen werden.
/// Der Pfad muss existieren, wenn er angegeben wird. Er wird nicht erstellt.</param>
/// <returns>Gibt die Anzahl der abgerufenen Attachments zurück. Im Fehlerfall wird -1 zurückgegeben.</returns>
public static int MsGraphEntityClientLoadAttachments(EntityData entity, bool embedInlineImages, string downloadPath)
E-Mail erstellen und versenden
/// <summary>
/// Versendet alle Send-Message-Entities welche übergeben werden.
/// </summary>
/// <param name="messageEntities">Die Nachrichten, welche gesendet werden sollen.</param>
/// <returns>Gibt die Anzahl der versendeten Nachrichten zurück. Im Fehlerfall wird -1 zurückgegeben.</returns>
public static int MsGraphEntityClientSendMessages(EntityListData messageEntities)
Termine erstellen und aktualisieren
/// <summary>
/// Erstellt die Termine neu oder aktualisiert bestehende Termine auf MS Graph Seite.
/// Attachments werden ebenfalls aktualisiert.
/// Es können mehrere Dateipfade mittels Semikolon getrennt werden.
/// Bsp.: "c:\temp\MyImage.png;c:\temp\pdf\MyDocument.pdf"
/// Bei Verwendung von InlineImages kann eine ID vor den Dateipfad geschrieben werden. Dafür muss der Trenner | verwendet werden.
/// Bsp. InlineId+Dateipfad: "my_inline_image_id|c:\temp\MyImage.png"
/// Im HTML-Teil des Termins kann das Image mit dieser ID referenziert werden.
/// Bsp.HTML: <img src="cid:my_inline_image_id">
/// Nach dem Erstellen/Aktualisieren wird das Entity wie folgt angepasst:
/// - die GraphId wird gesetzt/aktualisiert
/// - die SentDateTime wird gesetzt/aktualisiert
/// </summary>
/// <param name="appointmentEntities">Die Termine, welche erstellt oder aktualisiert werden sollen.</param>
/// <returns>Gibt die Anzahl der erstellten und aktualisierten Termine zurück. Im Fehlerfall wird -1 zurückgegeben.</returns>
public static int MsGraphEntityClientCreateOrUpdateAppointments(EntityListData appointmentEntities)
E-Mail-Ordner
/// <summary>
/// Ruft alle E-Mailordner sowie deren Unterordner ab und erzeugt Entities im pit.
/// Wenn die Entities bereits existieren, werden neue Werte in das Entity übertragen/aktualisiert.
/// Versteckte Ordner werden ebenfalls abgerufen.
/// </summary>
public static void MsGraphEntityClientReadAllMailFolders()
/// <summary>
/// Erstellt den angegebenen E-Mail-Ordner und liefert die Id und ParentFolderId als Ref-Parameter zurück.
/// </summary>
/// <param name="targetFolderPath">Zielpfad des Mail-Ordners.</param>
/// <param name="isHidden">Als versteckten Ordner erstellen.</param>
/// <param name="folderId">Gibt die Id des erstellten Ordners zurück.</param>
/// <param name="parentFolderId">Gibt die parentFolderId des erstellten Ordners zurück.</param>
/// <returns>Liefert true, wenn alles funktioniert hat, und false bei einem Fehler.</returns>
public static bool MsGraphClientCreateMailFolder(string targetFolderPath, bool isHidden, ref string folderId, ref string parentFolderId)
Kontakt-Ordner
/// <summary>
/// Ruft alle Kontaktordner sowie deren Unterordner ab und erzeugt Entities im pit.
/// Wenn die Entities bereits existieren, werden neue Werte in das Entity übertragen/aktualisiert.
/// </summary>
public static void MsGraphEntityClientReadAllContactFolders()
/// <summary>
/// Erstellt den angegebenen Kontakt-Ordner und liefert die Id und ParentFolderId als Ref-Parameter zurück.
/// </summary>
/// <param name="targetFolderPath">Zielpfad des Kontakt-Ordners.</param>
/// <param name="folderId">Gibt die Id des erstellten Ordners zurück.</param>
/// <param name="parentFolderId">Gibt die parentFolderId des erstellten Ordners zurück.</param>
/// <returns>Liefert true, wenn alles funktioniert hat, und false bei einem Fehler.</returns>
public static bool MsGraphClientCreateContactFolder(string targetFolderPath, ref string folderId, ref string parentFolderId)
Kontakte
/// <summary>
/// Exportiert die Kontakte nach MS Graph in den angegebenen Kontakt-Ordner.
/// Der Ordner muss bereits existieren. Dieser wird nicht erstellt.
/// Kontakte mit GraphId werden unter dem <paramref name="parentFolderPath"/> neu erstellt.
/// </summary>
/// <param name="contactEntities">Die Kontakte, welche erstellt werden sollen.</param>
/// <param name="parentFolderPath">Der Zielpfad der Kontakte.</param>
/// <returns>Gibt die Anzahl der erstellten Kontakte zurück. Im Fehlerfall wird -1 zurückgegeben.</returns>
public static int MsGraphEntityExportContacts(EntityListData contactEntities, string parentFolderPath)
/// <summary>
/// Aktualisiert den Kontakt in MS Graph.
/// Der Kontakt muss eine GraphId enthalten, sonst kann er nicht aktualisiert werden.
/// </summary>
/// <param name="contactEntity">Der Kontakt für die Aktualisierung.</param>
/// <returns>Gibt 1 zurück. Im Fehlerfall wird -1 zurückgegeben.</returns>
public static int MsGraphEntityUpdateContact(EntityData contactEntity)
/// <summary>
/// Löscht den Kontakt in MS Graph mittels Entity.
/// Der Kontakt muss eine GraphId enthalten, sonst kann er nicht aktualisiert werden.
/// Achtung: Das Entity wird bei Erfolg ebenfalls gelöscht.
/// </summary>
/// <param name="contactEntity">Der Kontakt für die Aktualisierung.</param>
/// <returns>Gibt 1 zurück. Im Fehlerfall wird -1 zurückgegeben.</returns>
public static int MsGraphEntityDeleteContact(EntityData contactEntity)
/// <summary>
/// Löscht den Kontakt in MS Graph mittels GraphId.
/// </summary>
/// <param name="graphId">Der Kontakt für die Aktualisierung.</param>
/// <returns>Gibt 1 zurück. Im Fehlerfall wird -1 zurückgegeben.</returns>
public static int MsGraphClientDeleteContact(string graphId)
Pit Meta-Klassen erzeugen
Um die Funktionen mit pit Entity-Klassen verwenden zu können, müssen die Metadaten der Klassen erstellt werden. Dies ist mithilfe der Methode MsGraphClientSetupMetadata möglich. Die Methode sollte ausschließlich im SysUser-Modus gerufen werden. Nach dem Erstellen der Entity-Klassen müssen die Berechtigungen händisch gesetzt werden, damit Anwender über Klassenformeln und das Addon die Enities erzeugen, bearbeiten und lesen können. Das SQL und die Tabellen müssen für bestimmte Entity-Klassen erzeugt werden. Danach müssen für diese Klassen die IDs generiert werden.
/// <summary>
/// Diese Methode erstellt alle Meta-Klassen und ihre Attribute in pit.
/// Alle Klassen, welche <see cref="IPitMetaEntity"/> implementieren werden als Meta-Klassen erzeugt.
/// </summary>
public static void MsGraphClientSetupMetadata()