8 Tage Windows Phone 8 | Tag #5: .NET 4.5 und C# 5.0

Geschrieben am von leitning

Die­ser Arti­kel ist Tag #5 der Serie 8 Tage Win­dows Phone 8 von Geert van der Cruijsen.

Der Ori­gi­nal­ar­ti­kel befin­det sich hier: 8 days of Win­dows Phone 8 — Day 5: .net 4.5 & C# 5.0.

8 Tage Windows Phone 8

Will­kom­men zurück zu mei­ner Arti­kel­se­rie 8 Tage Win­dows Phone 8. Heute, am fünf­ten Tag der Serie, reden wir über die neuen Fea­tures im .NET 4.5 Frame­work und in der Spra­che C# 5.0. Diese kön­nen Ihnen dabei hel­fen, tolle Win­dows Phone Anwen­dun­gen zu bauen. Die Fea­tures, auf die wir heute beson­ders ein­ge­hen wol­len, sind die Schlüs­sel­wör­ter async und await und der DataContractJsonSerializer.

day5

.NET Frame­work 4.5 und C# 5.0

Bei der Aktua­li­sie­rung einer Anwen­dung von Win­dows Phone 7 auf Win­dows Phone 8 aktua­li­sie­ren wir diese auch von Sil­ver­light auf das .NET 4.5 Frame­work und die C# 5.0 Spra­che. Damit bekom­men Win­dows Phone Ent­wick­ler einige neue Fea­tures, die nicht wirk­lich Teil des SDK sind, die aber extrem nütz­lich für Sie als Ent­wick­ler von mobi­len Anwen­dun­gen sind. Eines die­ser neuen Fea­tures ist das async und await Mus­ter. Damit wird das Bauen von asyn­chro­nen Anwen­dun­gen wesent­lich ver­ein­facht und trägt damit indi­rekt zu einer reak­ti­ven Benut­zer­schnitt­stelle für den End­nut­zer bei. Das andere Thema, auf das ich heute ein­ge­hen möchte, ist die Ver­wen­dung des Data­Con­tractJ­son­Se­ria­li­zer. Diese Klasse hilft Ihnen, zwi­schen Objek­ten und JSON Strings zu seria­li­sie­ren und zu dese­ria­li­sie­ren. Das ist sehr nütz­lich, wenn man aus einer App auf Dienste im Web zugreift.

Unglück­li­cher­weise ver­wen­den (noch?) nicht alle APIs im SDK die async und await Schlüs­sel­wör­ter. Web­Cli­ent und Htt­pWe­bRe­quest ver­wen­den die­ses Fea­ture nicht. Mög­li­cher­weise wer­den wir irgend­wann den Htt­p­Cli­ent wie unter Win­dows 8 ver­wen­den können.

In der Bei­spiel­an­wen­dung zum heu­ti­gen Arti­kel wollte ich idea­ler­weise die Demons­tra­tion des async/await-Patterns und des JSON Seria­li­zers kom­bi­nie­ren. Da wir das async/await-Pattern nicht ver­wen­den kön­nen, um eine Datei aus dem Web zu holen, laden wir ein­fach eine lokale Datei. Die APIs zum Zugriff auf lokale Dateien ver­wen­den die Klasse Task und damit das async/await-Pattern. Fan­gen wir also an, eine sehr ein­fa­che TODO-Listen-Anwendung zu bauen.

Erstel­len Sie ein neues Win­dows Phone 8 Pro­jekt und fügen Sie eine Klasse ToDo hinzu. Diese wer­den wir zur Beschrei­bung eines Ein­trags in der TODO-Liste ver­wen­den. Um diese Daten spä­ter in einer JSON Datei spei­chern zu kön­nen, fügen wir einige Attri­bute hinzu, damit der Data­Con­tractJ­son­Se­ria­li­zer weiß, wie die Daten in eine JSON Datei seria­li­siert wer­den sol­len. Fügen Sie das [Data­Con­tract] Attri­but der ToDo Klasse hinzu und das [DataMem­ber] Attri­but allen Eigen­schaf­ten, die nach JSON seria­li­siert wer­den sol­len. Stan­dard­mä­ßig wird der Seria­li­zer den Ele­men­ten in der JSON Datei die sel­ben Namen geben wie die ent­spre­chen­den Eigen­schaf­ten in Ihrer Klasse. Wenn Sie möch­ten, dass die Ele­mente in der JSON Datei einen ande­ren Namen haben, kön­nen Sie das DataMem­ber Attri­but ent­spre­chend ver­än­dern. Im Code unten sehen Sie dies am Bei­spiel der Eigen­schaft Con­tent. Das ent­spre­chende Feld in der JSON Datei wird den Namen „Text“ haben.

[DataContract]
public class ToDo
{   
   [DataMember]
   public string Title { get; set; }
 
   [DataMember]
   public DateTime Date { get; set; }

   [DataMember(Name="Text")]
   public string Content { get; set; }
 }

Nach­dem wir jetzt einen ein­fa­chen Con­tai­ner für unsere Objekte haben, las­sen Sie uns etwas Geschäfts­lo­gik mit dem Namen ToDo­Ser­vice erstel­len, um die Liste der Auf­ga­ben zu spei­chern und wie­der aus der Datei in einem loka­len Ord­ner (Local­Fol­der) zu laden. Local­Fol­der ist der Wur­zel­ord­ner Ihrer Anwen­dungs­da­ten — unter Win­dows Phone 7 war das Iso­la­ted Storage.

Als ers­tes fügen wir unse­rem ToDo­Ser­vice eine Methode hinzu, um die Liste der Auf­ga­ben zu speichern.

public async Task<string> SaveToDos()
{
   List<ToDo> todos = new List<ToDo>();

   todos.Add(new ToDo(){Title="todo 1", Date = DateTime.Now, Content="finish this series of blogposts"});
   todos.Add(new ToDo(){Title="todo 2", Date = DateTime.Now, Content="Pick up milk from the store"});
   todos.Add(new ToDo(){Title="todo 3", Date = DateTime.Now, Content="Wash my car"});

   var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;

   DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(List<ToDo>));
   MemoryStream ms = new MemoryStream();
   dcjs.WriteObject(ms,todos);

   string json = Encoding.UTF8.GetString(ms.ToArray(),0,(int)ms.Length);

   StorageFile todoFile = await localFolder.CreateFileAsync("todos.json",CreationCollisionOption.ReplaceExisting);

   using (var f = await todoFile.OpenStreamForWriteAsync())
   {
      await f.WriteAsync(ms.ToArray(),0,(int)ms.Length);
      f.Close();
   }

   return json; 
}

Beach­ten Sie das async Schlüs­sel­wort vor dem Rück­ga­be­typ in der Methode. Damit kann die Methode asyn­chron auf­ge­ru­fen wer­den und sie wird immer einen Task zurück­ge­ben, wel­cher den Rück­ga­be­wert beinhal­tet. In der Methode fül­len wir die Liste der Auf­ga­ben zunächst mit eini­gen Ein­trä­gen. Danach erstel­len wir einen Data­Con­tractJ­son­Se­ria­li­zer. Dabei geben wir im Kon­struk­tor an, wel­chen Typ wir seria­li­sie­ren wol­len. Wir ver­wen­den dann den Data­Con­tractJ­son­Se­ria­li­zer, um die Liste der Auf­ga­ben in eine JSON Zei­chen­kette zu seria­li­sie­ren. Die­sen geben wir am Ende der Methode zurück.

Sobald wir den JSON String haben, erstel­len wir eine neue Datei im loka­len Ord­ner, indem wir die Methode Crea­teFi­le­Async auf­ru­fen. Beach­ten Sie das await Schüs­sel­wort im Auf­ruf der Methode, wel­cher grob bedeu­tet, dass der Code unter­halb des Auf­rufs erst aus­ge­führt wird, wenn der asyn­chrone Auf­ruf abge­schlos­sen ist. Wenn die lokale Datei erstellt ist, schrei­ben wir ein­fach die JSON Zei­chen­kette in diese Datei und schlie­ßen den Stream.

Jetzt, wo wir die Auf­ga­ben­liste in die lokale Datei gespei­chert haben, las­sen Sie uns diese wie­der lesen und am Bild­schirm anzei­gen. Wir imple­men­tie­ren hierzu in unse­rem ToDo­Ser­vice eine wei­tere Methode mit dem Namen Get­To­Dos(). Diese liest die JSON Datei ein und dese­ria­li­siert diese zurück in die Liste der Aufgaben.

public async Task<List<ToDo>> GetToDos()
{
   var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;

   StorageFile todoFile = await localFolder.GetFileAsync("todos.json");
   DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(List<ToDo>));

   var stream = await todoFile.OpenStreamForReadAsync();
   var todos = dcjs.ReadObject(stream) as List<ToDo>;

   return todos;
}

Wir begin­nen wie­der, indem wir uns eine Refe­renz auf den loka­len Ord­ner und auf die JSON Datei holen. Nach­dem wir das Sto­ra­ge­File Objekt haben, erstel­len wir wie­der einen neuen Data­Con­tractJ­son­Se­ria­li­zer. Wir öffnen den Stream aus unse­rer Sto­ra­ge­File und über­ge­ben die­sen an den Data­Con­tractJ­son­Se­ria­li­zer, um die Daten zurück in eine Liste von Auf­ga­ben zu dese­ria­li­sie­ren. Damit sind wir fertig.

Um die Demo abzu­schlie­ßen, fügen wir der Haupt­seite eine Text­Box hinzu, in wel­cher wir die JSON Zei­chen­kette dar­stel­len. Wei­ter­hin bauen wir ein Items­Con­trol ein, wel­ches die Liste der Auf­ga­ben anzeigt.

<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
   <ScrollViewer>
      <StackPanel>
         <TextBlock x:Name="JsonText" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}"></TextBlock>
         <ItemsControl x:Name="TodoList" ItemTemplate="{StaticResource TodoItemTemplate}" Margin="0,12,0,0"></ItemsControl>
      </StackPanel>
   </ScrollViewer>
</StackPanel>

In der Code Behind Datei fügen wir nun alles zusam­men, um die Daten zu schrei­ben, zu lesen und anzuzeigen.

public async void SaveAndGetTodos()
{
   ToDoService ts = new ToDoService();
   string json = await ts.SaveToDos();
   List<ToDo> todos = await ts.GetToDos();
   JsonText.Text = json;
   TodoList.ItemsSource = todos;
}

Wenn wir unsere Demoan­wen­dung jetzt lau­fen las­sen, sehen wir den JSON String, wel­cher durch den Data­Con­tractJ­son­Se­ria­li­zer erstellt wurde und außer­dem die Liste der Auf­ga­ben im ItemsControl.

day5demo

Sie kön­nen das Bei­spiel­pro­jekt hier her­un­ter­la­den: http://sdrv.ms/QSJ2yx.

Hof­fent­lich hat Ihnen das Lesen die­ses Arti­kels Spaß gemacht und Sie haben etwas über async/await und den Data­Con­tractJ­son­Se­ria­li­zer gelernt. Mor­gen gibt’s mehr über eines der cools­ten Fea­tures im neuen SDK: die APIs zur Sprachsteuerung.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>