Windows 8 App mit Backend in der Cloud – Windows Azure Mobile Services

Wenn man eine Windows 8 App schreibt und persistente Daten zum Speichern hat, stellt sich über kurz oder lang die Frage, welche Backend-Lösung man für die Daten verwenden will. Windows Azure Mobile Services bieten hierbei eine einfache Lösung, um eine Datenbank in der Cloud für Windows 8 Apps zu nutzen.

In diesem Tutorial will ich anhand einer einfachen Windows 8 App, die Artikel in einer Einkaufsliste speichert, zeigen, wie man auf die Schnelle die Datenbank erstellen und für die App verwenden kann. Folgende Schritte werden wir durchgehen:

  • Vorbereitung
  • Einrichten eines Windows Azure Mobile Services
  • Erstellen einer Tabelle
  • Eine einfache Windows 8 App schreiben
  • Direkter Zugriff auf die Datenbank in Visual Studio

Vorbereitung

  1. Wir benötigen für unsere App Visual Studio und Windows Azure SDK. Falls ihr es noch nicht installiert habt, könnt ihr hier Visual Studio Express 2012 und Windows Azure SDK herunterladen.
  2. Um die Services von Windows Azure in Anspruch zu nehmen, ist auch Windows Azure Konto notwendig. Hier kann man sich für ein 90-Tage gratis Trial anmelden.
  3. Jetzt müssen wir die Mobile Services in unserem Azure Account noch aktivieren. Geht auf die Seite https://account.windowsazure.com und loggt euch mit eurer Live Id ein. Ihr klickt dann auf den Punkt Vorschaufeatures.20image
  4. Auf der Seite der Vorschaufeatures aktivieren wir die Mobile Services mittels Try it now.

Einrichten eines Windows Azure Mobile Services

Nachdem wir nun die Grundvoraussetzungen erfüllt haben, können wir mit unserer App beginnen. Wir wollen eine einfache Einkaufsliste entwickeln, in der wir Artikel eingeben können, die dann in einer Datenbank mittels Windows Azure Mobile Services gespeichert werden. So richten wir unser Windows Azure Mobile Service ein:

  1. Zuerst müssen wir uns im Windows Azure Management Portal unter https://manage.windowsazure.com mit der Live Id anmelden.

  2. In der unteren Leiste klickt Ihr auf Neu. 21image

  3. Danach wählt Ihr den Punkt Mobiler Service und klickt auf Erstellen.22image

  4. In dem Dialogfeld müsst Ihr einen Namen für das Mobile Service auswählen, der Teil der URL sein wird. Das heißt, wenn der Name bereits vergeben ist, müsst Ihr einen ähnlichen Namen wählen. Danach wählt ihr Eine neue SQL-Datenbankinstanz erstellen und North Europe als Region und klickt auf den Pfeil unten.23imageIm zweiten Schritt wählt ihr unter Server den Punkt Neuer SQL-Datenbankserver und gebt ein Username und Passwort an. Wichtig: merkt euch den Username und das Passwort, da ihr denselben Datenbankserver für weitere Mobile Services verwenden könnt. Falls ihr bereits einen Datenbankserver erstellt habt, dann wählt ihr unter Server diesen aus und gebt eure Anmelde-Daten für den Server an.24image

    Ihr habt jetzt ein Mobile Service erstellt, dass ihr ansprechen könnt. Bevor wir uns der App widmen, müssen wir noch eine Tabelle in unserer Datenbank erstellen.

Erstellen einer Tabelle

  1. In unserem Management Portal gehen wir auf Mobile Services und wählen das gerade von uns erstellte Mobile Service aus. Dort klicken wir auf Daten in der oberen Leiste. Danach gehen wir auf Eine Tabelle hinzufügen.25imageX9DRYOH126imagePA1RR73HDa wir in unserer Einkaufsliste Artikel speichern wollen, benötigen wir eine Tabelle namens Artikel.

    imageO2SKGM2Q

    Nun haben wir in unserem Mobile Service die Tabelle für unsere Artikel Objekte erstellt. Wenn wir auf unsere Tabelle jetzt klicken und auf Spalten gehen, sehen wir, dass diese Tabelle bereits eine Spalte namens Id besitzt.

    imageOWNJHDQ9

Eine einfache Windows 8 App schreiben

  1. Zunächst erstellen wir uns ein neues Projekt in Visual Studio unter Datei/Neu… . Wir wählen die Kategorie Windows Store unter C# nehmen die Leere App und geben MeineEinkaufsliste als Namen an.25image

  2. Links im Solution Explorer klicken wir mit rechter Maustaste auf References und dann auf Add reference.26image
    Unter Extensions klicken wir Windows Azure Mobile Services Managed Client an (Das setzt voraus, dass wir in der Vorbereitungsphase Windows Azure SDK installiert haben).27image

  3. Im Solution Explorer auf der rechten Seite können wir alle Dateien in unserem Projekt sehen. Wir öffnen durch Doppelklick die Dateien App.xaml.cs und MainPage.xaml.cs und fügen in beiden Dateien oben folgendes Statement ein:

     using Microsoft.WindowsAzure.MobileServices;
    
  4. In App.xaml.cs fügen wir folgenden Code gleich über dem Konstruktor der Klasse App hinzu:

     public static MobileServiceClient MobileService = new MobileServiceClient(
    
               "https://meineeinkaufsliste.azure-mobile.net/",
    
               "jdJuIxpihCodEilnMsCVIFORiMHuXm99"
    
           );
    

    Wir stellen hier eine Instanz für den MobileServiceClient bereit, wobei wir dem Konstruktor, die URL des Mobile Services und den Anwendungsschlüssel als Parameter übergeben. Diese zwei Werte müsst Ihr gemäß eurer App ersetzen.
    Die Werte findet Ihr, wenn Ihr im Azure Management Portal unter Mobile Services auf euer Mobile Service geht und oben Dashboard wählt. In der rechten Spalte befindet sich die URL des Mobile Services und in der unteren Leiste im Punkt Schlüssel Verwalten könnt ihr den Anwendungsschlüssel rauskopieren.

    28image

  5. In der Datei MainPage.xaml.cs schreiben wir eine Klasse für unsere Artikel Objekte. Ihr könnt den Code direkt oberhalb der MainPage Klasse einfügen.

     public class Artikel
     {
         public int Id { get; set; }
    
         [DataMember(Name = "bezeichnung")]
         public string Bezeichnung { get; set; }
    
         [DataMember(Name = "gekauft")]
         public bool Gekauft { get; set; }
     }
    

    Und dann fügen wir noch folgendes Statement oben im using Block hinzu:

     using System.Runtime.Serialization;
    

    Wir haben nun eine Klasse Artikel geschrieben, die eine Variable Bezeichnung für den Namen des Artikels und eine Variable Gekauft besitzt, um anzugeben, ob der Artikel noch ausständig ist oder bereits gekauft. Durch [DataMember(Name=”bezeichnung”)] haben wir sichergestellt, dass die Klassenvariable Bezeichnung einer Spalte in der Tabelle Artikel entspricht. Unsere Tabelle Artikel in unserem Mobile Service besitzt ein Dynamisches Schema. Wenn wir ein Artikel-Objekt an das Mobile Service schicken, werden automatisch die Spalten generiert.

    In der Klasse MainPage fügen wir folgende Variablen oberhalb dem MainPage()-Konstruktor:

     private MobileServiceCollectionView<Artikel> artikel;
     private IMobileServiceTable<Artikel> artikelTable =
                     App.MobileService.GetTable<Artikel>();
    

    Hier stellen wir eine Instanz der Tabelle aus unserem MobileService als artikelTable bereit und definieren eine Collection für unsere Artikel Objekte, die wir aus der Tabelle einlesen wollen.
    Dann fügen wir noch folgende Methoden in der Klasse hinzu.

     private async void InsertArtikel(Artikel art)
     {
         await artikelTable.InsertAsync(art);
         artikel.Add(art);
     }
    
     private async void UpdateCheckedArtikel(Artikel art)
     {
         await artikelTable.UpdateAsync(art);
         artikel.Remove(art);
     }
    
     private void RefreshArtikel()
     {
         artikel = artikelTable
             .Where(art => art.Gekauft == false)
             .ToCollectionView();
         //Artikelliste.ItemsSource = artikel;           
     }
    

    InsertArtikel und UpdateCheckedArtikel fügen das als Parameter übergebene Artikel Objekt in die Tabelle in unserem MobileService ein bzw ändern die Daten in der Update Methode. In der RefreshArtikel Methode lesen wir alle Artikel, die noch nicht gekauft wurden, aus der Tabelle in unsere Collection artikel. Wir wollen, dass diese Methode aufgerufen wird, sobald der User auf die Seite kommt, daher machen wir den Methodenaufruf in der OnNavigatedTo-Methode, die in der Vorlage bereits bereitgestellt wird.

     protected override void OnNavigatedTo(NavigationEventArgs e)
     {
         RefreshArtikel();
     }
    

    Jetzt fügen wir noch zwei EventHandler-Methoden in der Klasse hinzu.

     private void SaveButton_Click(object sender, RoutedEventArgs e)
     {
         //Artikel art = new Artikel
         //{ Bezeichnung = Artikelbezeichnung.Text};
    
         //InsertArtikel(art);
     }
    
     private void CheckBoxComplete_Checked(object sender, RoutedEventArgs e)
     {
         CheckBox cb = (CheckBox)sender;
         Artikel art = cb.DataContext as Artikel;
         UpdateCheckedArtikel(art);
     }
    

    In der SaveButton_Click-Methode behandeln wir das Ereignis, in dem ein Benutzer auf den Speichern Button klickt, nachdem er einen neuen Artikel eingegeben hat. Wir erstellen ein neues Artikel-Objekt und rufen die InsertArtikel-Methode zum Einfügen in die Tabelle auf. Da wir das User Interface noch nicht erstellt haben, kommentieren wir den Code aus, nachdem wir die Controls in der MainPage.xaml definiert haben.

    In der CheckBoxComplete_Checked-Methode behandeln wir das Ereignis, in dem ein Benutzer die Checkbox anklickt, um anzudeuten, dass der Artikel gekauft wurde. Hier rufen wir die UpdateCheckedArtikel-Methode auf.

  6. Wir gehen nun zu der Datei MainPage.xaml und  ersetzen das Grid-Element mit folgendem Code:

     <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
         <Grid.ColumnDefinitions>
             <ColumnDefinition Width="80"/>
             <ColumnDefinition Width="400"/>
             <ColumnDefinition Width="*"/>
         </Grid.ColumnDefinitions>
         <Grid.RowDefinitions>
             <RowDefinition Height="120"/>
             <RowDefinition Height="*"/>
         </Grid.RowDefinitions>
         <TextBlock Grid.Column="1" Text="Einkaufsliste" Style="{StaticResource PageHeaderTextStyle}" Margin="0"/>
         <StackPanel Grid.Column="1" Grid.Row="2" Margin="0,50,0,0">
    
             <TextBlock Text="Artikelbezeichnung:" Style="{StaticResource BasicTextStyle}"/>
             <TextBox x:Name="Artikelbezeichnung" Width="250" Height="30" HorizontalAlignment="Left"/>
             <Button Content="Speichern" Margin="0,10,0,0" Click="SaveButton_Click" />
         </StackPanel>
    
         <StackPanel Grid.Column="2" Grid.Row="2">
             <TextBlock Text="Meine Artikel:" Margin="0,0,0,20" Style="{StaticResource BasicTextStyle}"/>
             <ListView x:Name="Artikelliste">
                 <ListView.ItemTemplate>
                     <DataTemplate>
                         <StackPanel>
                             <CheckBox Name="CBgekauft" IsChecked="{Binding Gekauft, Mode=TwoWay}"
                                       Checked="CheckBoxComplete_Checked" Content="{Binding Bezeichnung}" />
                         </StackPanel>
                     </DataTemplate>
                 </ListView.ItemTemplate>
             </ListView>
         </StackPanel>
     </Grid>
    
  7. Jetzt fehlt noch das Auskommentieren des Codes in der SaveButton_Click-Methode in MainPage.xaml.cs, sowie das Auskommentieren der letzten Zeile (Artikelliste.ItemsSource = artikel; ) in der RefreshArtikel-Methode.

  8. Als letzten Punkt wollen wir noch den Look der App auf das helle Farbschema ändern. Dazu gehen wir in die App.xaml Datei und fügen im Application-Element das Attribut RequestedTheme mit dem Wert Light ein. Das Ganze sieht dann so aus:

     <Application
         x:Class="MeineEinkaufsliste.App"
         xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="using:MeineEinkaufsliste"
         RequestedTheme="Light">
    
  9. Nun können wir unsere App ausprobieren. Wenn ihr in Visual Studio F5 drückt, dann wird die App kompiliert und gestartet. Ihr könnt im linken Teil Artikelbezeichnungen eingeben, die in die Datenbank mittels Mobile Service eingefügt werden und im rechten Teil werden die aus der Datenbank ausgelesenen Artikel angezeigt. Bei der Abfrage nach der Artikel werden nur jene angezeigt, die den Wert false in der Gekauft Spalte haben. Der Wert false wird dann auf der Seite mit einer leeren Checkbox dargestellt.
    29image

Direkter Zugriff auf die Datenbank in Visual Studio

Wir haben bereits ein Mobile Service mit einer Datenbankinstanz eingerichtet und eine Tabelle erstellt. Weiters haben wir das aus den Eingabewerten erstellte Artikel Objekt in die Tabelle eingefügt und aus der Tabelle anhand der Spalte Gekauft selektiert ausgelesen. Wir haben also eine funktionierende Backend-Lösung, ohne eine einzige Zeile SQL geschrieben zu haben!

Es kann aber Fälle geben, in denen es praktischer ist, die Datenmanipulation direkt mit SQL zu erledigen als über eine grafische Oberfläche. Wenn wir beispielsweise eine weitere Spalte namens Menge in unserer Tabelle hinzufügen wollen, genügt es in unserer Klasse Artikel in MainPage.xaml.cs ein weitere Klassenvariable (als DataMember deklariert) namens Menge hinzuzufügen und im Interface Felder für das Einlesen und Ausgeben der neuen Information vorzusehen. Wegen des dynamischen Schema wird beim nächsten Einfügen eines Artikels mit Mengenangabe automatisch eine weitere Spalte in der Tabelle hinzugefügt. Alle unsere bisherigen Daten werden allerdings Null-Werte in der neuen Spalte haben. Wenn wir sinnvollere Werte für die Spalte Menge in den bisherigen Artikel Datensätzen haben wollen, ist es am schnellsten, dies mit einem UPDATE Statement in SQL zu realisieren. Dieses Szenario wollen wir nun durchspielen, damit wir sehen können, wie wir direkt auf die Datenbank unseres Azure Mobile Services zugreifen und SQL Code ausführen können.

  1. Als erstes ändern wir die Artikelklasse in MainPage.xaml.cs und fügen eine weitere Klassenvariable Menge ein, sodass unsere Artikelklasse so aussieht:

     public class Artikel
     {
         public int Id { get; set; }
    
         [DataMember(Name = "bezeichnung")]
         public string Bezeichnung { get; set; }
    
         [DataMember(Name = "gekauft")]
         public bool Gekauft { get; set; }
    
         [DataMember(Name = "menge")]
         public string Menge { get; set; }
     }
    
  2. Danach ändern wir die Methode für das Event des Buttonklicks beim Speichern. Wir wollen bei der unserem neuen Artikel Objekt, die vom Benutzer angegebene Menge miteinberücksichtigen. Unsere SaveButton_Click Methode sieht daher so aus:

     private void SaveButton_Click(object sender, RoutedEventArgs e)
     {
         Artikel art = new Artikel
         { Bezeichnung = Artikelbezeichnung.Text,
                 Menge = Menge.Text};
    
         InsertArtikel(art);
     }
    
  3. Nun fügen wir in der MainPage.xaml unmittelbar über die Definition für den Speichern Button die Zeilen, um ein Eingabefeld für die Artikelmenge zu erstellen.

     <TextBlock Text="Menge:" Style="{StaticResource BasicTextStyle}" Margin="0,15,0,0"/>
     <TextBox x:Name="Menge" Width="50" Height="30" HorizontalAlignment="Left"/>
    

    Gleich nach dem CheckBox Element in unserer ListView namens Artikelliste fügen wir diese Zeile ein:

     <TextBlock Name="Artikelmenge" Text="{Binding Menge}" Margin="27,0,0,5"/>
    

    Wenn wir jetzt unsere App starten (F5), so sehen wir dass wir jetzt Artikel mit Mengenangabe eingeben können und für alle Artikel wird die Mengenangabe anzeigt. Wenn wir jetzt auf unser Management Portal gehen und in unserer Tabelle Artikel (unter dem erstellten Mobile Services auf Daten klicken) den Tab Spalten in der oberen Leiste wählen, so sehen wir dass unsere Tabelle jetzt auch eine Spalte Menge besitzt.

    30image

    In unserer App sehen wir auch die neue Information der Artikelmenge.

    31image

  4. Bevor wir versuchen, auf die Datenbank direkt in Visual Studio zugreifen zu können, müssen wir noch sicherstellen, dass unsere IP als erlaubte Zugriffsquelle im Azure Management Portal gelistet ist. Zunächst wählt ihr unter Datenbanken, die DB Instanz eures Mobile Services. Dort findet ihr in der rechten Spalte den Link Zulässige IP-Adressen verwalten.32imageHier habt ihr nun zwei Möglichkeiten eure IP Adresse einzugeben. Entweder ihr übernimmt die vorgeschlagene IP unter Aktuelle Client-IP-Adresse, indem ihr auf den Pfeil daneben (rote Markierung) klickt oder ihr  gebt die IP bzw den IP Adressenbereich selbst ein (orange Markierung). Ich habe im Screenshot einige IP Adressen vom Screenshot entfernt, daher seht ihr dort einige leere Felder.33image

    Damit eure Eingabe übernommen wird, müsst ihr noch in der unteren Leiste auf Speichern klicken.

    34image

  5. In Visual Studio findet ihr am linken Rand den SQL Server Object Explorer. Dort klickt ihr auf das Icon, um eine neue SQL Instanz hinzuzufügen.

  6. 35imageIn dem Dialogfeld gebt ihr nun den Server-Namen und die Login-Daten für eure DB ein, die ihr beim Einrichten des Mobile Services im dritten Schritt eingegeben habt. Den Server-Namen findet ihr direkt nach dem Punkt Zuständige IP-Adressen verwalten, den ihr im vorigen Schritt dieses Tutorials gesehen habt.36image

  7. Jetzt wo eure Datenbank hinzugefügt ist, klicken wir im SQL Server Object Explorer auf das Icon für eine neue Query.37image
    Und dann wählen wir in der SQL Datei in der oberen Leiste im Drop Down Feld unsere Datenbankinstanz aus.38image

    Nun sind wir bereit im Fenster SQL Code zu schreiben und auszuführen. Beginnen wir mit einem einfachem SELECT Statement. Gebt im SQL Fenster den grün markierten Befehl ein. Vor dem Tabellennamen haben wir unseren Schema-Namen, der Name des Mobile Services in unserem Fall ein. Mit Strg + Shift + E können wir den Befehl ausführen oder wir klicken auf den rot markierten Pfeil. Darunter sehen wir im Ergebnisfeld unsere Ergebnisdaten, in diesem Falle alle Rows.

    39image

  8. Nun wollen wir alle Artikel, die in der Spalte Menge einen Nullwert besitzen auf einen sinnvollen Wert, beispielsweise 1, updaten. Dazu schreiben wir folgendes UPDATE Statement in das SQL Fenster und führen es wieder aus.

     UPDATE MeineEinkaufsliste.Artikel
    SET menge = '1'
    WHERE menge IS NULL
    GO
    

    Wenn wir jetzt wieder das obige SELECT Statement aus dem vorigen Schritt ausführen, so bekommen wir das erwartete Ergebnis.

    40image

Wir haben nun erfolgreich eine Windows 8 App geschrieben, die eine Backend in der Cloud hat. Wie ihr gesehen habt, ging das ganze sehr schnell und unkompliziert. Wir haben auch gesehen, wie wir die Datenbank direkt ansprechen können und unsere Daten mittels T-SQL manipulieren können. In einem späteren Teil werden wir uns anschauen, wie wir Daten validieren können, bevor wir diese in die Tabelle einfügen.

Hier sind noch alle Ressourcen für dieses Tutorial aufgelistet.

Ressourcen: