Als Beispiel für die einfachhe Handhabung betrachten wir den Zugriff mit C# auf die API mittels der .NET 3.5 Bibliothek. Das komplette Programm können Sie hier herunterladen.
Weiterführende Informationen zum Umgang mit OData-Schnittstellen, und zahlreiche weitere Codebeispiele in C# und VB finden Sie auch in der .NET Dokumentation.
Um auf die API zuzugreifen, muss man zunächst eine Datenservice-Referenz erstellen. Dies wird von Visual Studio durch ein paar Mausklicks und der Angabe der URI der LogMyTime API automatisch generiert. Die genaue Vorgehensweise hierzu ist in folgendem Artikel geschildert.
Nun kann eine Instanz einer solchen Api-Referenz erschaffen werden:
var dataSource = new APIDataSource(new Uri("http://api.logmytime.de/V1/Api.svc")); //falls auf der Serverseite weitere Eigenschaften in den Ressourcen hinzukommen sollten, //wollen wir, dass die Servicereferenz trotzdem noch funktioniert. Hierzu muss man unter //.NET noch die Eigenschaft 'IgnoreMissingProperties' auf true setzen. dataSource.IgnoreMissingProperties = true;
Für die Authentifizierung per HTTP Header weisen wir die Api-Referenz an, bei jedem Request eine Funktion namens AttachAuthHeader aufzurufen:
dataSource.SendingRequest += AttachAuthHeader;
Die Funktion fügt zur Athentifizierung den API-Schlüssel des Mitarbeiters als HTTP Header an:
private static void AttachAuthHeader(object sender, SendingRequestEventArgs e) { e.RequestHeaders.Add(new NameValueCollection{{"X-LogMyTimeApiKey", DER_APISCHLUESSEL}}); }
Nun können wir mit dem eigentlichen Zugriff auf die API beginnen. Die Service-Referenz besitzt für jeden Ressourcentyp der LogMyTime API ein IQueryable-Objekt, aus dem diese Ressourcen ausgelesen werden können.
Nehmen wir an, auf dem Server wären 2 aktive Projekte namens 'Mondlandung' und 'Marsexpedition', sowie ein abgelegtes Projekt namens 'Kühlschrank abtauen'.
Beispiel: Um die Namen aller Projekte und deren Status aufzulisten:
foreach (var project in dataSource.Projects) { Console.WriteLine(project.Name+": "+project.Active?"Aktiv":"Abgelegt"); }
Ausgabe:
Mondlandung: Aktiv Marsexpedition: Aktiv Kühlschrank abtauen: Abgelegt
Es können auch serverseitige SQL-ahnliche Befehle (sogenannte Query String Options) beim Lesezugriff ausgeführt werden.
Beispiel: Anstatt aller Projekte sollen nur die aktiven Projekte vom LogMyTime-Server geladen werden. Die Projekte sollen auch gleich serverseitig alphabetisch sortieren werden. Dazu muss man das vorherige Beispiel wie folgt abändern:
foreach (var project in dataSource.Projects .AddQueryOption("$filter", "Active") .AddQueryOption("$orderby", "Name") ) { Console.WriteLine(project.Name); }
Ausgabe:
Marsexpedition: Aktiv Mondlandung: Aktiv
Eine Dokumentation aller Query String Options finden Sie auf der OData-Webseite.
Die Service-Referenz unterstützt sogar Links der Ressourcen untereinander. Diese werden durch Eigenschaften in den Ressourcen-Stubs der Service-Referenz repräsentiert.
Beispielsweise sind bei LogMyTime der Projektname und die Tätigkeit keine unmittelbaren Eigenschaften einer Zeiteintrags-Ressource. Mit der Bibliothek kann man auf Projektname und Tätigkeit aber so zugreifen, als ob dies der Fall wäre. Man muss nur die Service-Referenz anweisen, die entsprechenden Child-Referenzen Project und Task beim Ladevorgang zu expandieren, also in dem gleichen Request mit zu laden.
Beispiel: Alle Zeiteinträge mit Projekt und Tätigkeit auflisten:
foreach (var timeEntry in dataSource.TimeEntries .Expand("Project") .Expand("Task")) { Console.WriteLine("Von {0} bis {1}: {2} / {3}", timeEntry.StartTime, timeEntry.EndTime, timeEntry.Project.Name, timeEntry.Task!=null?timeEntry.Task.Description:null); }
Ausgabe:
Von 27.07.2010 15:34:23 bis 27.07.2010 17:48:26: Marsexpedition / Recherche Von 27.07.2010 12:31:30 bis 27.07.2010 14:06:31: Marsexpedition / Meeting Von 27.07.2010 01:00:00 bis 27.07.2010 04:00:00: Mondlandung / Triebwerk B montieren ...
Der Schreibzugriff gestaltet sich ähnlich einfach. Für das Erstellen neuer Ressourcen muss der Ressourcen-Stub mit der AddTo{RessourceListenName}-Methode in die Service-Referenz eingefügt werden. Anschließend weist man die Service-Referenz an, die neue Ressource zum Server zu übertragen.
Beispiel: Ein neues aktives Projekt namens "Mondlandung" anlegen und dessen serverseitige ID ausgeben
Project newProject = new Project { Name = "Mondlandung", Active = true }; //Das neue Projekt in die API Servicereferenz einfügen dataSource.AddToProjects(newProject); //Änderungen an Server absenden SubmitChanges(dataSource); //Das Stub erhält automatisch die serverseitige ID des neuen Projektes: Console.WriteLine("Das Projekt wurde angelegt. Die Projekt-ID lautet: "+newProject.ID);
Beim Ändern von Ressourcen muss man der Service-Referenz explizit mitteilen, dass die am Referenz-Stub gemachten Änderungen mit dem Server synchronisiert werden sollen.
Beispiel: Das Projekt namens "Mondlandung" in "Mondlandungsexpedition" umbenennen:
//Projekt laden... var enumerator = dataSource.Projects .AddQueryOption("$filter", "Name eq 'Mondlandung'") .GetEnumerator(); enumerator.MoveNext(); Project project =enumerator.Current; //umbenennen... newProject.Name = "Mondlandungsexpedition"; //den Stub zum Synchronisieren auf den Server freigeben... dataSource.UpdateObject(newProject); //und zum Server übertragen SubmitChanges(dataSource);
Das Löschen ist ist ähnlich einfach wie das Erstellen von Ressourcen.
Beispiel: Das Projekt Namens "Mondlandung" löschen:
//Projekt vom Server laden... var enumerator = dataSource.Projects .AddQueryOption("$filter", "Name eq 'Mondlandung'") .GetEnumerator(); enumerator.MoveNext(); Project project =enumerator.Current; //Service-Referenz anweisen, die Ressource beim nächsten Synchronisieren zu löschen dataSource.DeleteObject(project); //änderungen an den Server übertragen SubmitChanges(dataSource);
Die LogMyTime API bietet zusätzlich zu ressourcentabellen auch noch einige Service-Operationen, die z.B. die Synchronisation von Daten stark vereinfachen und das Steuern der Stoppuhr über die API ermöglichen. Als Beispiel wird im Beispielprogramm ein ChangesDigest-Objekt mit den Änderungen der letzten 24 Stunden heruntergeladen.
Beispiel: ChangesDigest herunterladen
var uri = new Uri(String.Format("{0}/GetChangesDigest?LastSynchronizationTime={1}&IgnoreOtherUsersResources={2}", dataSource.BaseUri, referenceTime.ToString("s"), ignoreOtherUsersTimeEntries ), UriKind.RelativeOrAbsolute); var changesDigest = dataSource.Execute<ChangesDigest>(uri).ToList().First();
Weiterführende Informationen zum Umgang mit OData-Schnittstellen, und zahlreiche weitere Codebeispiele in C# und VB finden Sie auch in der .NET Dokumentation.