Passend zur Markteinführung des neuen Windows Phone 7 (WP7) haben wir uns überlegt, wie wir für einen Vortrag die aktuellen Technologien von Microsoft auf eine interessante und „präsentionstaugliche“ Art kombinieren können. Was dabei herausgekommen ist, möchte ich in den folgenden Beiträgen vorstellen.

im ersten Teil habe ich eine groben Überblick über das Projekt gegeben.

im zweiten Schritt haben wir Windows Azure Cloud Services einbezogen.

jetzt wollen wir untersuchen, was uns OData und WCF Data Services und das Entity Framework 4 (EF4) bringen können.

Warum OData ?

OData ist ein neuer Standard für den einfachen Austausch von Daten über das Internet.  Einfach heißt: es ist ein ein Format gewählt worden, das es möglichst vielen Technologien und Plattformen ermöglicht diese Daten zu beziehen und zu  verstehen. Interoperabilität ist damit endlich zur Realität geworden. Dafür hat man auf das bereits existierende AtomPub Protokoll aufgesetzt, und es um einige Features erweitert, die es für den Einsatz mit Datenobjekten optimieren.

OData ist zwar von Microsoft entworfen und unterstützt, es wird aber nicht durch Patente und Lizenzpolitik zum Risiko für langfristige Investitionen durch Drittanbieter (siehe Java: Oracle vs. Google) . Microsoft garantiert das in diesem Dokument Microsoft Open Specification Promise (OSP).

Der wichtigste Punkt im OData Standard ist jedoch die URL-basierte Abfragemöglichkeit. Es wurde eine einfache Syntax geschaffen, die es ermöglicht, über die URL SQL-ähnliche Filter zu konstruieren. Dieses Feature sowie die Möglichkeit Daten per REST zu verarbeiten, ermöglicht es praktisch jeder technischen Plattform die über HTTP kommunizieren kann, OData Daten zu verwenden.

Durch das einfache XML/JSON Format sowie die einfache Abfragemöglichkeit ist OData prädestiniert für die Verwendung in offenen Internet Szenarien.

OData Services stellen Daten typischerweise generell zur Verfügung, die Art der Verwendung ist nicht festgelegt. Ein Beispiel sind öffentliche APIs von großen Anbietern wie z.B. Netflix. Einige interessante Beispiele findet man hier.

Hier kann jeder Entwickler mit “seiner” Technologie auf den gesamten Katalog des Online Video Anbieters zugreifen um Applikationen zu bauen, z.B. für Smartphones oder das Web (Mashups)

Ein anderes, ebenso interessantes Szenario findet man bei einigen amerikanischen Behörden: für den einfachen Datenaustausch zwischen verschiedenen Einrichtungen hat sich OData als bestens geeignet erwiesen.

Microsoft verwendet OData auch in seinen eigenen Produkten, wichtig zu nennen sind hier z.B. Sharepoint, Reporting Services, sowie das Ad Hoc BI Tool PowerPivot.  Dieser Tatsache haben wir es wohl zu verdanken, dass auch auf der Tool Seite (.NET) gute Unterstützung vorhanden ist. So können wir mit wenigen Zeilen Code eine Datenbank per OData “veröffentlichen”.

Dazu verwenden wir in unseren Beispiel Entity Framework 4 und WCF Data Services (a.k.a. ADO.NET Data Services a.k.a. Astoria)

Das Entity Framework erklären wir hier nicht, wer mehr wissen will findet alle Infos hier.

Unser Datenmodell ist schnell beschrieben :-)

image

Wir haben eine Tabelle TVDEmp, hier werden alle teilnehmenden Trivadis Mitarbeiter hinterlegt. In der Tabelle TVDLunch werden die aktuellen Daten für das Mittagessen gespeichert: Zeit, Ort und Mitarbeiter Kurzname (Nickname). Zu den Details kommen wir noch. Wir haben bewusst keine “echte” Relation (Foreign Key Constraint)  modelliert, um die Dinge einfach zu halten. Somit kann jede Entität für sich allein verwendet werden, ohne Joins. In einer “echten” Applikation könnte man als zusätzliche Abstraktionsschicht in der Datenbank einen View Layer definieren, der nach verschiedenen Kriterien optimiert werden kann ( Performance, Zugriffsberechtigung, etc.). Objektorientierte Zeitgenossen können das Gleiche mit einem verfeinerten Entity Model erzielen, oder mit Hilfe von LINQ.

Wie kommen Die Daten ins Internet ?

Das geht ziemlich einfach: wir brauchen ein Visual Studio Projekt, das eine WCF Data Services Komponente aufnehmen kann. ich empfehle hier ein ASP.NET MVC Projekt zu erzeugen, damit geht es perfekt.

einen WCF Data Service hinzufügen:

Dialog box WCF Data Services

mit dem Hinzufügen dieser Komponente ist eigentlich schon fast alles erledigt. Wir müssen der Komponente nur  noch erklären , wo das EF Model ist, und welche Objekte mit welchen Rechten aufgerufen werden können. Dazu modifizieren wir den Code geringfügig:

public class WcfDS : DataService< TVDLunchWeb.Models.TVDLunchEntities>
 {
     // This method is called only once to initialize service-wide policies.

     public static void InitializeService(DataServiceConfiguration config)
     {
        
         config.SetEntitySetAccessRule("TVDEmp", EntitySetRights.All);
         config.SetEntitySetAccessRule("TVDLunch", EntitySetRights.All);
                     
         // Make the remaining entity sets read-only.
         config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);

         config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
         
         

     }
     protected override void HandleException(HandleExceptionArgs args)
     {
         // need this to create a breakpoint and debug errors
         base.HandleException(args);
     }

 }

Den Exceptionhandler empfehle ich dringend, hier kann man zur Laufzeit einen breakpoint für das Debuggen setzen. So erleichtert man sich das Finden von Fehlern ungemein, da man das HandleExceptionArgs args Objekt komfortabel in Visual Studio untersuchen kann.

jetzt können wir das Projekt kompilieren und aus VS heraus testen. Im Browser geben wir dazu folgende URL ein:

http://localhost:4332/MyService.svc/

die Portnummer und den Namen des Services bitte entsprechend anpassen.

dann sollte etwas in dieser Art erscheinen:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<
service xml:base="http://localhost:4332/WcfDS.svc/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app"
>
  <
workspace
>
    <
atom:title>Default</atom:title
>
    <
collection href="TVDEmp"
>
      <
atom:title>TVDEmp</atom:title
>
    </
collection
>
    <
collection href="TVDLunch"
>
      <
atom:title>TVDLunch</atom:title
>
    </
collection
>
  </
workspace
>
</
service
>
 

 

 

 

 

Das ist eine einfache strukturelle Beschreibung unseres Services.

Ein kleiner Test zeigt uns, ob wir auch Daten aus der Datenbank laden können. Dazu geben wie den Namen einer Entität in der URL an:

http://localhost:4332/MyService.svc/TVDLunch

IE zeigt Odata Daten als Feed an.

image 

hier ist das XML dazu (Testdaten) :

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="http://localhost:4332/WcfDS.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title type="text">TVDLunch</title>
  <id>http://localhost:4332/WcfDS.svc/TVDLunch</id>
  <updated>2011-01-03T13:32:41Z</updated>
  <link rel="self" title="TVDLunch" href="TVDLunch" />
  <entry>
    <id>http://localhost:4332/WcfDS.svc/TVDLunch(0)</id>
    <title type="text"></title>
    <updated>2011-01-03T13:32:41Z</updated>
    <author>
      <name />
    </author>
    <link rel="edit" title="TVDLunch" href="TVDLunch(0)" />
    <category term="TVDLunchModel.TVDLunch" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
      <m:properties>
        <d:Id m:type="Edm.Int32">0</d:Id>
        <d:Nickname>mik</d:Nickname>
        <d:LunchTime m:type="Edm.DateTime">2010-08-31T12:00:00</d:LunchTime>
        <d:LocationText>Pianissimo</d:LocationText>
        <d:Comment>I’m really hungry!</d:Comment>
        <d:GeoPoint>POINT(8.86871337890625, 50.84410451978965)</d:GeoPoint>
      </m:properties>
    </content>
  </entry>
…
  </feed>

Man kann schön sehen, dass die Daten tatsächlich als fortlaufender Feed geliefert werden. die “…” habe ich eingefügt, um Platz auf dieser Seite zu sparen.

Die Felder innerhalb des <entry> Tags beinhalten die Daten aus unserer Tabelle. Zu den einzelnen Feldern (speziell das GeoPoint Feld) erkläre ich später mehr.

Der WCF Data Service ist damit bereit! Er kann übrigens uch per REST auch Daten einfügen, updaten und löschen.

Für unsere App haben wir noch 2 Stores Procedures in das System integriert. Diese können ebenfalls per URL aufgerufen werden und somit z.B. von einer Ajax Routine in JavaScript verwendet werden.

das machen wir im nächsten Beitrag.

Geht das auch mit Azure ?

Selbstredend. Wir brauchen eine Visual Studio Azure Solution, in das wir das Web Projekt (als Web Role) einhängen.

(Keine Ahnung wie das geht ? hier  ist ein guter Startpunkt für Tutorials und Dokumentation) .

In dieses Projekt fügen wir einen WCF Data Service ein , siehe oben. Das ist schon alles.

Es macht natürlich Sinn, ab hier auch eine SQL Azure Datenbank zu verwenden. Dazu muss nur noch der Connectionstring in der Web.config Datei geändert werden.

Nach dem Deployment können wir die Daten von der Azure Webadresse herunterladen. Wilkommen in der Cloud!

Möglichweise wird es mit Azure noch einfacher werden, einen OData Web Service zu erstellen.

Dazu gibt es einen Versuch auf der Seite https://www.sqlazurelabs.com/ConfigOData.aspx. Ich habe es aber leider bis jetzt nicht zum Laufen gebracht.

Und wie geht’s weiter?

Als nächstes bauen wir ein mit ASP.NET MVC ein Frontend, das die OData Daten per Ajax abruft und zurückschreibt.

Hier werden wir auch das Bing Maps API kennenlernen.

Im darauffolgenden Beitrag werden wir dann “endlich” zur Windows Phone 7 App kommen.

Bis dahin: beste Wünsche für 2011!