, Q ta c. N a ví LI T D m je NE he nu O. o hr D mn Za T, A , a S es R E vic r Se
Přístup k datům a webové služby pro bohatě vybavené internetové aplikace (RIA)
Silverlight je obsáhlá platforma pro internetové aplikace, jež rozšiřuje možnosti vývojářů .NET i na webové prohlížeče a umožňuje využívat funkce, které již byly k dispozici v aplikacích WPF. Tato technologie otevřela nové možnosti organizacím, jež mohou nyní své webové aplikace vytvářet s využitím existujících znalostí v oblasti vývoje .NET mnohem rychleji a spolehlivěji než kdy dříve. Silverlight kromě toho přináší i rozsáhlou sadu ovládacích prvků, kterou rozšiřuje prostřednictvím sady nástrojů Silverlight Toolkit. Seznam kapitol a příloh: • • • •
Začínáme se Silverlightem Základy datových vazeb Režimy a oznamování Správa seznamů, šablon a konvertorů • WCF, webové služby a mezidoménové zásady • Předávání entit prostřednictvím služeb WCF • Silverlight a ADO.NET Data Services
• Užití služeb RESTful prostřednictvím tříd WebClient a HttpWebRequest • Informační kanály a Silverlight • Využívání služeb RESTful pomocí Silverlightu na Amazonu • Příloha: Přehled ADO.NET Data Services • Příloha: Ladění aplikace Silverlightu
Johnova kniha vám pomůže pochopit oblast bohatě vybavených internetových aplikací (RIA) a ukáže vám, jak lépe pracovat s daty. Shawn Wildermuth, Microsoft MVP (C#)
Tohle je bezpochyby ta nejlepší samotatná kniha datových službách a Silverlightu, kterou jsem kdy přečetl. Je to skutečně nepostradatelný pomocník. Jesse Liberty, expert na Silverlight a Microsoft senior program mananager
John Papa je držitelem titulu MCSD.NET (Microsoft Certified Solution Developer) a MVP (Most Valuable Professional) pro C#. Je také mluvčím INETA (International .NET Association). S distribuovanými architekturami od Microsoftu pracuje více než deset let. Napsal více než 60 článků a je autorem (nebo spoluautorem) několika knih věnujícím se přístupu k datům s využitím ASP.NET, WPF, Silverlightu, ADO.NET, XML a SQL Serveru.
E N C Y K L O P E D I E
Z O N E R
P R E S S
Pod tímto logem vycházejí publikace určené pro každého vážného zájemnce o práci s počítačem. Od ryze praktických příruček a průvodců až po komplexní publikace o všem, co potřebuje grafik, webdesignér, vyvojář či programátor při každodenní práci. Na slevy, které můžete získat a vydavatelský plán, v němž vedle knih domácích odborníků najdete celou řadu titulů světově uznávaných autorů, se informujte na adrese vydavatelství. Věrným čtenářům je určen výhodný PRÉMIOVÝ PLUS PROGRAM. DOPORUČENÁ CENA: 359 KČ KATALOGOVÉ ČÍSLO: ZR901
Zoner Press tel.: 532 190 883 fax: 543 257 245 e-mail: knihy@zoner.cz www.zonerpress.cz
ZONER software, a.s., Nové sady 18, 602 00 Brno
ISBN 978-80-7413-041-0
9 7 8 8 0 7 4
1 3 0 4 1 0
Silverlight – datové služby
Silverlight – datové služby
Silverlight datové služby
John Papa
John Papa
Silverlight datové služby
John Papa
Kap_0o.indd 1
29.6.2009 16:18:04
Data-Driven Services with Silverlight John Papa © ZONER software, a.s., 2009. Authorized translation of the English edition of Data-Driven Services with Silverlight 2, ISBN 9780596523091 © 2008 John Papa. This translation is published and sold by permision of O'Reilly Media, Inc., the owner of all rights to publish and sell the same. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from O'Reilly Media, Inc. © ZONER software, a.s., 2009. Autorizovaný překlad originálního anglického vydání knihy Data-Driven Services with Silverlight 2, ISBN 9780596523091 © 2008 John Papa. Překlad je vydán a prodáván s výslovným svolením O'Reilly Media, Inc., vlastníkem veškerých práv na vydání i prodej tohoto titulu. Žádná část této publikace nesmí být reprodukována nebo předávána žádnou formou nebo způsobem, elektronicky ani mechanicky, včetně fotokopií, natáčení ani žádnými jinými systémy pro ukládání bez výslovného svolení O'Reilly Media, Inc.
Silverlight – datové služby Autor: John Papa Copyright © ZONER software, a.s. Vydání první v roce 2009. Všechna práva vyhrazena. Zoner Press Katalogové číslo: ZR901 ZONER software, a.s. Nové sady 18, 602 00 Brno Překlad: Veronika Matějů Odborná korektura: RNDr. Jan Pokorný Šéfredaktor: Ing. Pavel Kristián DTP: Pavel Kristián, ml. © Ilustrace na obálce: O'Reilly Media, Inc. Informace, které jsou v této knize zveřejněny, mohou byt chráněny jako patent. Jména produktů byla uvedena bez záruky jejich volného použití. Při tvorbě textů a vyobrazení bylo sice postupováno s maximální péčí, ale přesto nelze zcela vyloučit možnost výskytu chyb. Vydavatelé a autoři nepřebírají právní odpovědnost ani žádnou jinou záruku za použití chybných údajů a z toho vyplývajících důsledků. Všechna práva vyhrazena. Žádná část této publikace nesmí být reprodukována ani distribuována žádným způsobem ani prostředkem, ani reprodukována v databázi či na jiném záznamovém prostředku či v jiném systému bez výslovného svolení vydavatele, s výjimkou zveřejnění krátkých částí textu pro potřeby recenzí. Veškeré dotazy týkající se distribuce směřujte na: Zoner Press ZONER software, a.s Nové sady 18, 602 00 Brno tel.: 532 190 883, fax: 543 257 245 e-mail: knihy@zoner.cz www.zonerpress.cz
ISBN 978-80-7413-041-0
Kap_0o.indd 2
29.6.2009 16:19:21
Věnováno mé rodině: Colleen, Haley, Madelyn, Elle a brzy i Landonovi. Jste pro mě skutečným požehnáním.
Kap_0o.indd 3
29.6.2009 16:19:21
Podrobný obsah Předmluva
11
Úvod
13
Kapitola 1
Začínáme se Silverlightem
23
Význam přístupu k datům
23
Jdeme na to
24
Funkce Silverlightu 2
25
Podpora jazyků a technologie .NET Framework
26
Model pro popis webových služeb a jejich operací
27
Volná vázanost datových služeb
27
Nový model ovládacích prvků
27
LINQ to Objects a LINQ to XML
28
LINQ
28
Rozšíření jazyka
30
Automatické vlastnosti v C#
30
Inicializátory objektů
33
Inicializátory kolekcí
34
Rozšiřující metody
35
Implicitní typy proměnných
37
Anonymní typy/Implicitní typy
37
Anonymní typy a LINQ
38
Shrnutí
Kapitola 2
38
Základy datových vazeb Silverlightu
39
Život bez vazby
40
Datové vazby v Silverlightu
45
Pravidlo 1: FrameworkElement
46
Pravidlo 2: Závislostní vlastnost
47
Rozšířený zápis vazby XAML Vlastnosti rozšiřující vazby
Kap_0o.indd 4
50 51
29.6.2009 16:19:21
5 Zjednodušená vazba Vazba za běhu
53
Vytváření vazeb za běhu
54
Odebrání vazby
57
Vlastnost DataContext
58
DataContext a Source
59
Přenos vlastnosti DataContext
60
Vytváření vazeb v nástroji Blend
62
Shrnutí
66
Kapitola 3
Režimy a oznamování
Režimy vazeb
67 68
OneTime
68
OneWay
70
TwoWay
71
Režimy bez oznamování
72
Oznamovat či neoznamovat
78
Oznamování
78
Implementace rozhraní INotifyPropertyChanged
79
Přidání oznamování
84
Možnosti přepracování kódu (refactoring)
87
Shrnutí
Kapitola 4
90
Správa seznamů, šablon a konvertorů
Vazby k ovládacím prvkům založeným na seznamech
91 91
Nastavení vlastnosti ItemsSource
92
Úvahy o režimu vazby
94
Šablony a řádky
95
Datové šablony DataTemplate jako zdroje
95
Komplikovanější datové šablony DataTemplate
97
Výběr položek Využívání různých režimů vazeb
Kap_0o.indd 5
52
100 104
29.6.2009 16:19:21
6 Seznamy a oznámení
105
Kolekce ObservableCollection<T>
106
Změna seznamu objektů List<T>
106
Změna kolekce ObservableCollection<T>
110
Konvertory
111
Rozhraní IValueConverter
112
Konverze
112
Shrnutí
Kapitola 5
116
WCF, webové služby a mezidoménové zásady
117
Webové služby ASMX
117
Vytvoření webové služby ASMX
118
Začněme příkladem
119
Vytváření webové služby ASMX
120
Odkazování na webovou službu ASMX
123
Vrácení kolekce ObservableCollection<T> Využívání webové služby ASMX
123 124
Znovu ty vazby
124
Vytvoření třídy proxy
128
Asynchronní volání
129
Asynchronní dokončování
129
Spuštění webové služby ASMX
130
Mezidoménová volání a zásady
131
Mezidoménová omezení
132
Překračování hranice
132
Sledování požadavků
132
Soubor zásad Silverlightu
133
Soubor crossdomain.xml
135
Shrnutí přístupu mezi doménami
136
Vytvoření služby WCF spolupracující se Silverlightem
Kap_0o.indd 6
137
Vytváření webové služby WCF
137
Vazby
138
Nastavení služby WCF
138
29.6.2009 16:19:21
7 Vyvolání služby WCF
143
Volání služeb vytvořených jinými vývojáři
145
Shrnutí
149
Kapitola 6
Předávání entit prostřednictvím služeb WCF
Předávání entit mezi fyzickými vrstvami
151 151
Entity doménového modelu
152
Silverlight a entity
153
Implicitní serializace
153
Atributy serializace
157
Jak to dát vše dohromady
159
Využívání LINQ to SQL v Silverlightu
168
Serializace entity LINQ to SQL
169
Vytváření entit pomocí LINQ to SQL
169
Obsluha modelu LINQ to SQL
171
Využívání entit LINQ to SQL ze Silverlightu
174
Silverlight a Entity Framework
176
Vytvoření modelu Entity Framework
176
Využívání entit Entity Framework ze Silverlightu
180
Shrnutí
181
Kapitola 7
Užití služeb RESTful prostřednictvím tříd WebClient a HttpWebRequest 183
Základy služeb RESTful Základní webové požadavky HTTP
184
Webové služby RESTful poskytují prostředky
184
Jedinečné identifikátory URI
185
Struktura služby RESTful
186
WebClient Příprava na využívání služby RESTful pomocí WebClient
Kap_0o.indd 7
183
188 190
Vyvolání služby RESTful pomocí třídy WebClient
193
Vytváření XAML pro uživatelské rozhraní
195
Vyvolání služby pomocí třídy WebClient
197
29.6.2009 16:19:21
8 Zpracování odpovědi pomoci LINQ to XML
199
Indikace průběhu
203
HttpWebRequest
206
Třída HttpWebRequest v akci
209
Práce se zpětným voláním
210
Křížení vláken
211
Vlákna a třídy WebClient a HttpWebRequest
212
Shrnutí
Kapitola 8
212
Využívání služeb RESTful pomocí Silverlightu na Amazonu
213
Nejnovější trend: Cloud Services
213
Vytvoření nákupního košíku Amazonu
214
Akce RESTful
215
Vyhledávání knih
220
Parsování knih pomocí LINQ to XML
223
Vazby výsledků hledání
230
Operace nákupního košíku
234
Shrnutí
Kapitola 9
239
Vytváření služeb RESTful a využívání aplikace SilverTwit
Vytvoření služeb RESTful pomocí WCF
242
Vytváření služby RESTful
242
Vytváření rozhraní služby
243
Konfigurace služby RESTful
243
Definování kontraktu
244
Využívání služeb REST
248
Výchozí hodnoty
250
Stavové kódy HTTP
251
Obsluha JSON
Kap_0o.indd 8
241
252
Definování odpovědi JSON
253
LINQ to JSON
254
Zpracování produktů pomocí LINQ to JSON
256
29.6.2009 16:19:21
9 Odesílání dat do služby RESTful
262
Definování metod POST
263
Odesílání formátu JSON a XML
265
Případová studie: SilverTwit Architektura SilverTwit
269
Uživatelské rozhraní SilverTwit
269
Webové služby RESTful SilverTwitWS
273
Cachování
277
Tweeting
278
Shrnutí
Kapitola 10
281
Informační kanály a Silverlight
283
Poskytování obsahu informačních kanálů
283
Požadování informačního kanálu
285
Čtení obsahu informačního kanálu
288
Vazba informačního kanálu
289
Konvertory
291
Mezidoménové zásady
296
Seskupování informačních kanálů
299
Shrnutí
302
Kapitola 11
Silverlight a ADO.NET Data Services
Přehled ADO.NET Data Services
303 304
Metody HTTP
304
Formáty zpráv
305
Metadata
309
Využití vlastních datových zdrojů
Kap_0o.indd 9
268
309
Pravidla přístupu
313
Adresování RESTful
314
Možnosti URI
315
Vytvoření třídy proxy
316
Asynchronní dotaz LINQ
317
29.6.2009 16:19:21
10 ADO.NET Data Services a Entity Framework
321
Vytváření služeb na datovém modelu entit
322
Přístup pro čtení
322
Rozšíření klientského modelu
325
Zapojení aplikace
332
Význam oznámení
334
Zpožděné načítání
336
Interceptory dotazů
339
Interceptory změn
339
Rozšiřování operací služby
341
Další možnosti ukládání
342
Vkládání a skupiny objektů
343
Optimistická souběžnost
346
Shrnutí
PŘÍLOHA A
349
Přehled ADO.NET Data Services
351
Metody HTTP
351
System.Data.Services.Client
351
System.Data.Services
353
Možnosti URI v ADO.NET Data Services
354
Operátory URI v ADO.NET Data Services
354
Funkce URI v ADO.NET Data Services
355
PŘÍLOHA B
Ladění aplikace Silverlightu pomocí nástrojů pro kontrolu HTTP
357
Fiddler2
357
Web Development Helper
363
Firebug
365
Rejstřík
Kap_0o.indd 10
367
29.6.2009 16:19:21
11
Předmluva
Vzpomínám si, jak jsem v březnu 2006 seděl v přeplněné místnosti v Las Vegas a čekal, až někdo z Microsoftu zahájí svou přednášku s názvem „WPF/E“ a byl jsem zvědavý, o čem bude. Během následující hodiny měli účastníci možnost procházet první barevné prezentace a animace v prohlížeči na různých platformách operačních systémů. Všichni jsme odcházeli plni nadšení a ptali jsme se, co dalšího tento malý vedlejší projekt s krycím názvem „WPF/E“ přinese. Nyní již samozřejmě víme, že z WPF/E se stal Microsoft Silverlight. Nevěděli jsme však, kolik energie a potenciálu tato nová platforma přinese. Pravděpodobně žádná jiná platforma od příchodu .NET Framework nevzbudila mezi vývojáři tolik zájmu. Silverlight je obsáhlá platforma pro internetové aplikace, jež rozšiřuje možnosti vývojářů .NET i na prohlížeče a umožňuje využívání funkcí, které byly k dispozici již v aplikacích WPF (Windows Presentation Foundation).Tato technologie otevřela nové možnosti organizacím, jež mohou nyní své webové aplikace vytvářet s využitím existujících znalostí v oblasti vývoje .NET mnohem rychleji a spolehlivěji než kdy dříve. Silverlight představuje také novou konkurenci mezi dalšími interaktivními platformami, je výzvou pro přední společnosti na trhu a nutí všechny k přinášení inovací. První veřejné vystoupení Silverlightu se uskutečnilo v malé místnosti stranou od běžného ruchu konference společnosti Microsoft a Silverlight se rychle stal platformou pro vývojáře usilující o zdokonalování svých internetových aplikací. Samozřejmě víme, že aplikace nejsou tvořeny jen barevnými schématy či animacemi. Většina těch, kdo si prohlížejí „tradiční“ obchodní aplikace, ví, že v uživatelském rozhraní existuje jen málo točících se obdélníků, jež lze využívat k provádění každodenních operací v oblasti služeb zákazníkům, lidských zdrojů či systémů pro správu objednávek. Každá platforma, jež chce přežít v jakékoli or-
Kap_0o.indd 11
29.6.2009 16:19:21
12 ganizaci, musí být schopna zajišťovat základní činnosti na základě informací poskytovaných koncovými uživateli. Pro každou aplikaci jsou nejdůležitější data. Vymaníme-li se z „tradičního“ pojetí aplikací, i hry online jsou založeny na datech v určité formě. Svět technologií je obklopen daty, jež přicházejí a odcházejí z aplikací, ať již ve formě informačních kanálů, uživatelských vstupů, automatických služeb atd. – data vládnou. Na Silverlightu jako platformě pro vás může být důležité cokoli, ale data budou vládnout také ve všech vašich aplikacích. Ať již budete vyvíjet další skvělou hru, rozšířené uživatelské rozhraní aplikace pro lidské zdroje či kiosek na letišti, vaše aplikace bude vždy pracovat s daty. Pro úspěšnou implementaci aplikací je nezbytné pochopit různé způsoby přijímání a poskytování dat v rámci Silverlightu. Na Silverlightu je skvělé to, že se v podstatě jedná o .NET! Většinu svých stávajících znalostí o přístupu k datům můžete využít i při implementaci další platformy. Silverlight však vývojářům nabízí několik jedinečných příležitostí a možná i výzev. Díky svým zkušenostem v oblasti práce s daty na platformách Microsoft přináší John Papa specifický pohled na práci s daty na platformě Silverlightu. Ať již jde o tradiční webové služby ASP.NET, Windows Communication Foundation, informační kanály RSS či datové zdroje RESTful, pomohou vám Johnovy zkušenosti pochopit, jak tyto různé zdroje spolupracují se Silverlightem a jaké jsou nejlepší postupy při jejich implementaci. John vás provede jednotlivými koncepty a upozorní na nástroje a postupy, díky nimž dosáhnete úspěchu při vývoji svých aplikací v Silverlightu. Tato kniha by měla najít své místo v knihovně každého vývojáře aplikací Silverlightu. Podrobný popis přístupu k datům prostřednictvím Silverlightu je nepostradatelným průvodcem pro každého, kdo pracuje s daty. John podrobně vysvětluje, proč byste měli postupovat určitými způsoby a díky tomu lépe pochopíte, co se děje v zákulisí při přistupování Silverlightu k datům. Bez ohledu na to, jak budete tuto knihu využívat – ať již jako průvodce nebo jako příručku – stane se pro vás neocenitelným pomocníkem při získávání zkušeností, ale i později při vaší práci. Po přečtení této knihy se ze mne stal lepší vývojář v oblasti aplikací Silverlightu a bezpochyby bude velkým přínosem i pro vás. – Tim Heuer Program Manager, Microsoft
Kap_0o.indd 12
29.6.2009 16:19:21
Kapitola 1 Začínáme se Silverlightem
V Silverlightu lze vytvářet nejenom stylová rozhraní, ale také interaktivní aplikace pro různé prohlížeče. Ale co samotné aplikace v Silverlightu? Ne jen vložit video nebo pěkně vypadající sadu tlačítek, ale chodící, hovořící, plně funkční obchodní aplikaci. Samozřejmě že chcete mít také velmi elegantní rozhraní. Dobrá zpráva je, že díky Silverlightu 2 můžete mít všechno najednou. V této kapitole se budeme věnovat některým kritickým oblastem, s nimiž byste se měli seznámit, abyste mohli vyvíjet aplikace Silverlightu řízené daty, přičemž součástí budou i požadované instalace a nástroje. Než začnete vyvíjet aplikace pomocí Silverlightu, je důležité pochopit hlavní rozdíly mezi verzemi Silverlightu 1 a 2. Těmito rozdíly se budeme v této kapitole zabývat a dozvíte se, proč je každé zdokonalení v Silverlightu důležité pro vývoj aplikací řízených daty. Jedním s podstatných vylepšení v Silverlightu 2 je možnost psát kód .NET. Vývojáři tak mohou využívat svých stávajících schopností a vytvářet propracované aplikace Silverlightu. Při vývoji těchto aplikací lze používat i funkce jazyka .NET 3.5 v Silverlightu, jako je například LINQ a implicitní typy proměnných. V této kapitole si některá z těchto rozšíření jazyka .NET 3.5 probereme, protože se s nimi budete setkávat v celé knize. Projdeme si také jednotlivé kroky při vytváření jednoduché aplikace Silverlightu řízené daty.
Význam přístupu k datům Za pestrými uživatelskými rozhraními, přehráváním videí a stylovými šablonami se v Silverlightu nachází propracovaná struktura, jež dobře spolupracuje s různými typy datových zdrojů. Aplikace Silverlightu běží v prohlížeči klientského počítače, kde mezi nimi je Internet a jakákoliv serverová aplikace. Aplikace Silverlightu jsou odpojeny od vzdálených datových zdrojů, takže musí při odesílání a přijímání dat komunikovat se vzdálenými servery prostřednictvím různých typů webových služeb.
24
Kapitola 1: Začínáme se Silverlightem
Silverlight nabízí několik způsobů pro získání dat ze vzdálených serverů pomocí HTTP a soketů. K nejoblíbenějším a nejužitečnějším metodám patří komunikace s webovou službou založenou na SOAP na vzdáleném serveru (viz kapitoly 5 a 6) a příjem dat ze služby REST (viz kapitoly 7 až 9). V rámci Silverlightu je k dispozici několik nástrojů a metod pro příjem dat, práci s daty, vázání dat, prezentaci uživateli a zpracování všech aspektů aplikace řízené daty. Většina aplikací vyžaduje určitý typ interakce dat. Data mohou pocházet z databáze, informačního kanálu RSS, webové služby nebo služby REST, jež vrací data ve formátu Plain Old XML (POX). Aplikace Silverlightu mohou různým způsobem komunikovat se službami a vracet data. Ačkoli může být Silverlight velmi obsáhlým a výkonným nástrojem pro konečné uživatele, pro aplikaci jsou důležitá data a jejich doručování. V posledních letech získával přístup k datům různé významy. Termín přístup k datům skutečně popisuje přistupování k datům z libovolného počtu zdrojů. To může znamenat přístup k datům z databáze přímo prostřednictvím ADO.NET, ADO.NET Entity Framework, NHibernate, LLBLGen Pro, Enterprise Library nebo nějakého vlastního obchodního objektu a vrstvy přístupu k datům. Může jít také o přístup k datům prostřednictvím webových služeb, ASMX, Windows Communication Foundation (WCF), informačních kanálů RSS, webových služeb ve stylu REST a požadavků HTTP. K datům lze tedy přistupovat různě a po jejich získání je často nutné data určitým způsobem zpracovat. K uspořádání získaných dat do vhodnější formy vývojáři často využívají LINQ. Všechny tyto faktory definují přístup k datům a všechny postupy lze využívat přímo či nepřímo pomocí Silverlightu.
Jdeme na to Silverlight je skvělý nástroj určený pro návrhy propracovaných rozhraní, jež fungují v různých prohlížečích. Silverlight je díky rozsáhlé podpoře programování možným řešením pro obchodní aplikace. V rámci této knihy se seznámíte s vytvářením vizuálně a funkčně vyzrálých aplikací prostřednictvím Silverlightu. Než začneme s příklady, je třeba nainstalovat a nakonfigurovat programy potřebné pro Silverlight 2. Nainstalujte si verzi Silverlight 2 runtime, abyste mohli zobrazovat a spouštět aplikace Silverlightu v prohlížeči. Verze runtime funguje (a je oficiálně podporována) v prohlížečích Internet Explorer, Google Chrome, Firefox a Safari. Runtime je k dispozici pro operační systém Windows a Mac OS X. Silverlight 2 podporují následující prohlížeče: • Microsoft Internet Explorer verze 6.0, 7.0 a 8.0 beta • Mozilla Firefox verze 1.5, 2.0 a 3.0 • Apple Safari verze 2.0 a 3.0 beta • Google Chrome Nástroj Silverlight 2 Tools je k dispozici jako doplněk Visual Studia 2008 a umožňuje vytvářet aplikace Silverlightu 2 pomocí .NET a Silverlightu 2. Při instalaci doplňku Silverlight Tools
Silverlight – datové služby
25
se nainstaluje i Silverlight 2 runtime a Silverlight 2 SDK. Silverlight 2 SDK obsahuje příklady, dokumentaci a nástroje pro vývoj aplikací Silverlightu. Pro vývoj a práci se Silverlightem 2 jsou vyžadovány následující komponenty. Všechny jsou součástí jednoho instalačního souboru: • Silverlight 2 Runtime. • Silverlight 2 SDK. • Silverlight 2 Tools for Visual Studio. Níže uvedené nástroje pro ladění mohou velmi pomoci při hledání potíží v komunikaci aplikací a služeb Silverlightu 2. Všechny jsou bezplatné a mohou vyjasnit důvod potíží a pomohou určit vhodná řešení. V příloze B naleznete tipy a triky pro práci s těmito nástroji při ladění komunikace mezi Silverlightem a službami. • Firebug (pro Firefox). • Web Development Helper (pro Internet Explorer). • Fiddler2 (pro veškeré zachytávání síťového provozu). Doporučuje se také instalace Visual Studia 2008 a Expression Blend s SP1. Visual Studio 2008 je skvělé pro úpravy XAML, využívání IntelliSense a samozřejmě pro psaní kódu .NET pro aplikace Silverlightu. Expression Blend se skvěle hodí pro uspořádání složitých návrhů a rozvržení v rámci Silverlightu. Jedná se o hodnotné nástroje, jejichž funkcí byste měli při vývoji se Silverlightem využívat.
Funkce Silverlightu 2 Silverlight 2 s sebou přináší podporu pro kód .NET v aplikacích Silverlightu, nejde však o jediné podstatné zdokonalení. V tabulce 1.1 je uveden přehled hlavních vylepšení v Silverlightu 2, přičemž některá z nich jsou základem pro vývoj aplikací řízených daty pomocí Silverlightu. Tyto funkce jsou v tabulce 1.1 zvýrazněny, protože je třeba seznámit se s tím, jak mohou vývojářům pomoci při vytváření spolehlivých aplikací řízených daty se Silverlightem. Tabulka 1.1. Klíčové funkce Silverlightu Nové funkce v Silverlightu
Poznámky
Podpora jazyků a technologie .NET Framework
Silverlight podporuje kompatibilní část .NET Framework a programovací jazyky Visual Basic, Visual C#, IronRuby a IronPython.
Datové vazby a oznamování
V Silverlightu jsou nyní k dispozici datové vazby a oznamování založené na XAML s využitím rozhraní INotifyCollectionChanged a INotifyPropertyChanged.
26
Kapitola 1: Začínáme se Silverlightem
Tabulka 1.1. Klíčové funkce Silverlightu Nové funkce v Silverlightu
Poznámky
Izolované úložiště
Silverlight 2 může ukládat informace v chráněné oblasti na klientském počítači.
Smluvní a mimosmluvní datové služby: webové služby RSS založené na JSON, REST, SOAP, POX a Atom
Prostřednictvím Silverlightu jsou k dispozici různé datové služby. To zjednodušuje čtení dat z webových služeb.
Síťový přístup do různých domén
Silverlight 2 může přistupovat ke službám, jež nepocházejí ze serveru s aplikací Silverlightu2.
LINQ, lambda výrazy, rozšiřující metody a inicializátory objektů
Součástí Silverlightu je LINQ to Objects, LINQ to XML a LINQ to JSON sloužící k definování dotazů pro složité datové struktury.
Podpora rozložení (layout) StackPa-
Silverlight 2 podporuje tři významné panely rozložení nativní pro WPF a XAML.
nel, Grid a Canvas
Sada ovládacích prvků a panelů s možností vazby
Silverlight 2 přináší celou řadu ovládacích prvků, jež lze integrovat do aplikací Silverlightu 2 a lze vytvářet jejich vazby s datovými zdroji.
Společnost Microsoft chtěla původně vydat Silverlight 2 jako Silverlight 1.1, avšak po všech provedených zdokonaleních společnost usoudila, že nová verze je dostatečně odlišná na to, aby si zasloužila své vlastní číslo verze.
Když se podíváte na funkce uvedené v tabulce 1.1, je zřejmé, že Silverlight 2 přináší mnoho významných nových schopností. Je důležité, abyste se seznámili s každým vylepšením, jež přímo ovlivňuje vývoj aplikace řízené daty. Mnoho z nich si v následujících kapitolách podrobně popíšeme, nyní si je tedy pouze stručně představíme.
Podpora jazyků a technologie .NET Framework Vývoj aplikace Silverlightu je jednoznačně mnohem jednodušší, pokud můžete využít své zkušenosti s vývojem .NET. Počínaje schopností psát kód .NET v klientské aplikaci Silverlightu pro zpracování různých aspektů dané aplikace, včetně obsluhy událostí, přes využívání rozsáhlé platformy .NET Framework a vytváření složitých uživatelských ovládacích prvků. Silverlight 2 runtime obsahuje malou, ale výkonnou podmnožinu knihovny .NET Framework, takže vývojáři mohou využívat své stávající znalosti .NET a přejít na Silverlight s vynaložením minimálního úsilí.
Silverlight – datové služby
27
Model pro popis webových služeb a jejich operací Silverlight může komunikovat s webovými službami založenými na SOAP (např. prostřednictvím WCF nebo ASMX) a předávat definované datové struktury mezi klientem Silverlightu a vzdáleným serverem. Tyto služby vystaví s využitím jazyka WSDL kontrakt, s nímž může klient komunikovat vytvářením tříd proxy. Tento kontrakt definuje služby, jež lze volat, a způsob jejich volání. Vystavuje také datové struktury, jež lze předávat do služeb a ze služeb. To je klíčové pro vystavování webových služeb, jež vrací nebo přijímají serializovatelné jednotky jako parametry. Díky smluvnímu rozhraní může Silverlight komunikovat se vzdálenými službami, jež vracejí entity z LINQ to SQL, NHibernate, ADO.NET Entity Framework, nebo i vlastní modely doménových entit. Umožňuje také komunikaci se službami třetích stran založenými na SOAP, jež vystavují WSDL, jako je například Live Search.
Volná vázanost datových služeb Silverlight může využívat datové služby také bez vytváření tříd proxy prostřednictvím SOAP, RSS, Atom, JSON, POX nebo REST. K dispozici je mnoho zdrojů informací, jež vrací data prostřednictvím nesmluvní služby. Například Digg.com (http://www.digg.com), Amazon.com (http://www.amazon.com), Twitter.com (http://www.twitter.com) a Flickr.com (http://www.flickr.com) vystavují služby REST, jež vrací XML. Aplikace Silverlightu mohou požadovat informace ze všech těchto služeb a výsledky pak integrovat do aplikace. Těmto oblastem se budeme velmi podrobně věnovat v kapitolách 7 až 9, přičemž se také dozvíte, jak s nimi lze komunikovat mezi různými doménami a jak zpracovat XML a JSON, jež mohou vrátit prostřednictvím LINQ to XML a LINQ to JSON.
Nový model ovládacích prvků Nový model ovládacích prvků v Silverlightu 2 velmi usnadňuje vytváření aplikací Silverlightu. Nové ovládací prvky lze uspořádat v rámci panelů rozvržení (layout) XAML, jako je Grid, Canvas a StackPanel a vytvářet tak propracovaná rozhraní. Ovládací prvky podporují vlastnosti datových vazeb a závislostí založených na XAML, jimž se budeme podrobně věnovat v kapitolách 2 až 4. Silverlight 2 přináší více než dvacet ovládacích prvků, s jejichž pomocí lze vytvářet klientské aplikace Silverlightu. Nabízí panely rozvržení (layout), jako je například Grid, Canvas a StackPanel a několik ovládacích prvků pro vstup, jež lze upravovat s využitím šablon a stylů. Obsah některých ovládacích prvků lze zcela nahradit a vytvořit tak složitější řešení. Můžete například nahradit záhlaví ovládacího prvku Grid řadou ovládacích prvků, jež umožní seřadit DataGrid. Lze také nahradit výchozí vzhled tlačítka jiným prvkem, jako je Ellipse a vyplnit jej dalším prvkem FrameworkElement, například obrázkem. S ovládacími prvky se blíže seznámíte v kapitolách 2 až 4, v nichž je také vysvětleno, jak s nimi fungují datové vazby a jaké jsou nejvhodnější postupy pro vazby a prezentace dat. Na obrázku 1.1 jsou znázorněny ovládací prvky dostupné
28
Kapitola 1: Začínáme se Silverlightem
v Expression Blend 2 se SP1 a na obrázku 1 je přehled ovládacích prvků, jež jsou k dispozici ve Visual Studiu 2008.
LINQ to Objects a LINQ to XML Silverlight 2 podporuje využívání LINQ to Objects, což může zjednodušit dotazování dat v polích a kolekcích v aplikaci Silverlightu. LINQ to XML (také podporovaný v aplikacích Silverlightu 2) je velmi užitečný při využívání nesmluvních datových služeb, jež vrací XML. XML lze načítat do různých knihoven, avšak využití objektů LINQ to XML umožňuje dotazovat XML prostřednictvím známé a výkonné syntaxe LINQ. Pomocí LINQ lze také kombinovat XML a objektové datové struktury ve stejném dotazu LINQ. V mnoha příkladech uvedených v této knize budeme LINQ v určité podobě používat k dotazování dat z XML nebo objektů.
Obrázek 1.1 Ovládací prvky Silverlightu 2 zobrazené v Expression Blend
LINQ Aplikace řízené daty vytvořené v Silverlightu ve velké míře využívají rozšíření jazyka LINQ a .NET 3.5, jak si ukážeme v mnoha příkladech v této knize. Tyto funkce jsou důležité a stojí
Silverlight – datové služby
29
tedy za to seznámit se s tím, jak fungují. V jazycích C# 3 a Visual Basic (VB) 9 byla představena rozšíření, z nichž některá jsou základní pro psaní dotazů s LINQ. Aplikace Silverlightu mohou využívat například XML, JSON, objekty, entity z LINQ to SQL a entity z ADO.NET Entity Framework a další. Aplikace Silverlightu často potřebují získávat hodnoty z polí a (nebo) seznamů vlastních entit (např. List<T>). V těchto případech je LINQ to Objects užitečný, protože umožňuje dotazovat jakýkoli seznam IEnumerable. Ačkoli lze XML využívat a spravovat prostřednictvím různých knihoven .NET, jako je například XmlReader, LINQ to XML nabízí jednodušší a často výkonnější způsob využití XML.
Obrázek 1.2 Ovládací prvky Silverlightu 2 zobrazené ve Visual Studiu 2008
Aplikacím Silverlightu to usnadňuje využívání XML ze zdrojů RSS nebo služeb REST a zpracovávání dat, aniž by došlo k rozvláčným smyčkám. Dotazy LINQ se mohou také připojit k se-
30
Kapitola 1: Začínáme se Silverlightem
znamu objektů a XML, což je užitečné v případě, že aplikace získává data z více zdrojů. V několika kapitolách této knihy budeme pracovat s LINQ to Objects a LINQ to XML na příslušných místech, kde jich mohou aplikace Silverlightu využívat. LINQ to Entities se velmi často používá při dotazování modelu Entity Data Model, který je vytvářen ADO.NET Entity Framework. ADO.NET Entity Framework vytváří Entity Data Model, jenž mapuje objektově orientovaný pojmový model entit do relačního úložiště, jako je například SQL Server (ačkoli ADO.NET Entity Framework podporuje model poskytovatelů, takže jsou podporovány i další databázové servery, jako je Oracle). Dotazy se píší pomocí LINQ to Entities proti pojmovému modelu a dotazy se překládají prostřednictvím mapovací vrstvy na příkazy SQL, jež se provádějí oproti relačnímu úložišti. Po vrácení entity z dotazu LINQ to Entities lze entity serializovat a předat do dalších vrstev aplikace. Klientská aplikace Silverlightu by například mohla požadovat entitu ze služby WCF na vzdáleném serveru, jenž vystavuje entity z modelu Entity Data Model. Aplikace Silverlightu by pak na tyto entity mohla použít také LINQ to Objects. Čtvrtou podobou LINQ, které se budeme v této knize věnovat, je LINQ to SQL. LINQ to SQL umožňuje mapování 1:1 z entit na objekty SQL Server. Nepodporuje tak obsáhlé schéma mapování jako ADO.NET Entity Framework; nemá ani model poskytovatelů, takže funguje pouze s SQL Serverem. Pomocí LINQ to SQL můžete psát například dotazy vracející entity, jež lze serializovat a předat do aplikace Silverlightu.
Rozšíření jazyka Verze .NET 3.5 s sebou přinesla několik rozšíření jazyka .NET. Tato rozšíření jsou spolu s funkcemi důležitou součástí tvorby dotazů pomocí LINQ. V této části si ukážeme několik klíčových funkcí jazyka, včetně následujících: • Automatické settery (metoda pro zápis)/gettery (metoda pro čtení) vlastností. • Inicializátory objektů. • Inicializátory kolekcí. • Metody rozšíření. • Implicitní typy proměnných. • Anonymní typy. Rozšíření jazyka .NET 3.5 jsou znázorněna na obrázku 1.3.
Automatické vlastnosti v C# Vytváření vlastností může být velmi redundantní proces, zvláště pokud gettery a settery neobsahují jinou logiku, než je získávání a nastavování hodnoty privátního pole. Použití veřejných polí by sice zkrátilo délku kódu, tato pole však mají několik nevýhod. Nejpodstatnější nevýhodou je to, že veřejná pole nejsou plně podporována vazbami dat.
Silverlight – datové služby
31
Jednou z možností, jak se vyhnout psaní kódu pro privátní pole a jeho veřejný getter a setter vlastností, je použití refaktorizačního nástroje. Automatické možnosti však umožňují psát méně kódu a přesto získat privátní pole a jeho veřejný getter a setter. Inicializátor kolekce Inicializátor objektu
Vložený inicializátor objektu
Anonymní typ Implicitně typovaná proměnná Obrázek 1.3 Přehled rozšíření jazyka .NET 3.5
C# automatické vlastnosti podporuje, VB nikoli.
Pomocí zkrácené syntaxe vytvoříte automatickou vlastnost. Kompilátor pak za vás vygeneruje privátní pole a veřejný setter a getter. V příkladu 1.1 mají třídy Customer2 a Address2 několik privátních polí, jež jsou vystavena prostřednictvím řady odpovídajících veřejných getterů a setterů vlastností. Příklad 1.1 Explicitní gettery a settery v C# public class Customer2 { private int id; private string companyName; private Address2 companyAddress; public int ID { get { return id; } set { id = value; }
32
Kapitola 1: Začínáme se Silverlightem } public string CompanyName { get { return companyName; } set { companyName = value; } } public Address2 CompanyAddress { get { return companyAddress; } set { companyAddress = value; } }
} public class Address2 { private int id; private string city; private string state; public int ID { get { return id; } set { id = value; } } public string City { get { return city; } set { city = value; } } public string State { get { return state; } set { state = value; } } }
Příklad 1.2 ukazuje, jak lze stejného výsledku dosáhnout pomocí automatických vlastností, přičemž je třeba napsat méně kódu, než v příkladu 1.1. Třídy Customer a Address používají automatické vlastnosti k vytvoření vlastností tříd a nevyžadují tolik kódu pro definování pole a jeho getteru a setteru vlastností. Příklad 1.2 Automatické vlastnosti public class Customer
Silverlight – datové služby
33
{ public int ID { get; set; } public string CompanyName { get; set; } public Address CompanyAddress { get; set; } } public class Address { public int ID { get; set; } public string City { get; set; } public string State { get; set; } }
Inicializátory objektů Inicializátory objektů umožňují předávat pojmenované hodnoty pro každou veřejnou vlastnost, jež pak bude použita k inicializaci objektu. Pomocí kódu uvedeného v příkladu 1.3 byste například mohli inicializovat instanci třídy Customer. Příklad 1.3 Vytváření a inicializace třídy C#
Customer customer = new Customer(); customer.ID = 1001; customer.CompanyName = "Foo"; customer.CompanyAddress = new Address();
VB
Dim customer As New Customer() customer.ID = 1001 customer.CompanyName = "Foo" customer.CompanyAddress = New Address()
Pokud však využijete inicializátory objektů, můžete vytvořit instanci třídy Customer pomocí syntaxe uvedené v příkladu 1.4. Příklad 1.4 Využití inicializátorů objektů C#
Customer customer = new Customer { ID = 1001, CompanyName = "Foo", CompanyAddress = new Address() };
VB
Dim customer = New Customer() With _
Kapitola 5 WCF, webové služby a mezidoménové zásady
Silverlight 2 přináší obrovské množství nástrojů, s jejichž pomocí lze vytvářet propracovaná uživatelská rozhraní. Může také využívat různé služby v síti nebo v Internetu. Díky schopnosti komunikovat s různými typy webových služeb několika způsoby (například prostřednictvím služeb RESTful, poskytování obsahu informačních kanálů a služeb SOAP) mohou aplikace Silverlightu využívat funkce těchto služeb. Klienti Silverlightu přináší uživatelům silný zážitek a díky schopnosti komunikovat s různými službami je Silverlight skvělou volbou pro interaktivní aplikace a aplikace založené na službách. V této kapitole si ukážeme, jak lze vytvářet webové služby ASMX a WCF (Windows Communication Foundation) a jak s nimi komunikovat z klientských aplikací Silverlightu. Nejdříve vytvoříte službu ASMX založenou na SOAP, kterou využívá aplikace Silverlightu. Seznámíte se s několika aspekty komunikace založené na službách a dozvíte se, jak nastavit asynchronní komunikaci z klientů Silverlightu do služeb ASMX a WCF, jak implementovat obsluhy, využívat výsledky a zpracovávat výjimky. V této kapitole také probereme, jak mohou klienti Silverlightu vytvářet a využívat služby WCF a ukážeme si několik způsobů, jakými lze data předávat do služeb a ze služeb. Na obrázku 5.1 vidíte služby a jak s nimi Silverlight může komunikovat. Všechny služby by se měly chránit proti tomu, aby je využívali klienti, kteří nemají oprávnění. Mezidoménové zásady řeší tuto úroveň ochrany pro služby ASMX a WCF, ale také pro služby, jež se samy nepopisují, včetně služeb založených na REST, RSS a Plain Old XML (POX). Flash i Silverlight nabízejí schéma souborů XML, jež lze navrhnout tak, aby byl povolen nebo zakázán přístup klientů k těmto typům služeb. V této kapitole se dozvíte, jak tyto soubory fungují a naleznete zde několik tipů k jejich vytváření.
Webové služby ASMX Interakce s webovými službami ASMX je v současné době běžná. Umíte-li vytvářet a využívat webové služby ASMX, nemělo by být obtížné vytvořit webovou službu ASMX, kterou může
118
Kapitola 5: WCF, webové služby a mezidoménové zásady
využívat klientská aplikace Silverlightu. Pokud byste například chtěli využívat webovou službu ASMX z klienta ASP.NET, bylo by nutné přidat odkaz na webovou službu ASMX, vytvořit pro ni proxy a synchronně nebo asynchronně volat službu. Jediný rozdíl spočívá v tom, že klient Silverlightu může volat webovou službu pouze asynchronně. Aplikace Silverlightu
Služby WFC
Webové služby ASMX
Obrázek 5.1 Webové služby a Silverlight
Typy služeb, jež lze využívat z klientských aplikací Silverlightu, mají určitá omezení. Například služby WCF musí používat vazbu basicHttpBinding a služby podporující vlastní hlavičky SOAP nejsou podporovány.
Chcete-li využívat webovou službu ASMX, je nutné ji nejdříve vytvořit (pokud ještě neexistuje). Poté definujete účel služby (vystavované akce nebo metody). Klientská aplikace Silverlightu musí odkazovat na službu. Jakmile bude aplikace Silverlightu obsahovat odkaz na službu, vytvoří proxy pro službu a obsluhy pro asynchronní volání jejích metod. Nakonec může aplikace Silverlightu vyvolat službu a využít její výsledky.
Vytvoření webové služby ASMX Vývojáři budou obecně komunikovat buď s existující webovou službou, nebo vytvoří webovou službu pro vlastní účely. V této kapitole si ukážeme několik variací webových služeb a způsoby, jak s nimi lze komunikovat z klientů Silverlightu. Nejdříve se dozvíte, co potřebujete k vytvoření webové služby ASMX a ke komunikaci z klientské aplikace Silverlightu. Zkušební aplikace Silverlightu, kterou vytvoříme, umožní uživateli odesílat e-mailové zprávy. Protože klient Silverlightu nemá přístup ke jmennému prostoru System.Net.Mail, musí komunikovat se serverem, jenž mu umožní odesílat e-mailové zprávy. Klient by jinak mohl vyvolat výchozí poštovní aplikaci a použít ji k odeslání zprávy. Řešení založené na serveru je však často výhodnější, protože umožňuje mnohem více úprav. V aplikaci Silverlightu na obrázku 5.2 může uživatel jednoduše zadat informace pro e-mailovou zprávu a klikne na tlačítko Send via ASMX, aplikace Silverlightu vytvoří proxy pro webovou službu ASMX, přidá obsluhu události pro zpracování vráceného volání webové služby ASMX
Silverlight – datové služby
119
a asynchronně vyvolá webovou službu. Webové službě jsou předány informace z klientské aplikace Silverlightu, jež pak služba použije k odeslání e-mailu příjemci (příjemcům).
Obrázek 5.2 Poštovní klient Silverlightu
Obrázek 5.3 Řešení EmailServiceSample
Začněme příkladem Řešení příkladu se nachází ve složce s kódem pro kapitolu 5. Řešení má název EmailServiceSample a obsahuje pět projektů, jejichž názvy vidíte na obrázku 5.3. Projekt SilverlightEmailClient je projekt Silverlightu s klientem, který je znázorněn na obrázku 5.2. Projekt SilverlightEmailClientWeb je webová aplikace, jež hostí aplikaci Silverlightu; použijete ji k otestování klienta Silverlightu.
120
Kapitola 5: WCF, webové služby a mezidoménové zásady
Projekt ASMXEmailService obsahuje webovou službu ASMX, jež bude volána z projektu SilverlightEmailClient. Projekt EmailLibrary obsahuje jednoduchou třídu .NET s názvem Mail,
kterou zkušební kód používá k odeslání e-mailové zprávy prostřednictvím třídy MailMessage jmenného prostoru System.Net.Mail. Posledním projektem je WCFEmailService. Tento projekt obsahuje webovou službu WCF, jež nabízí stejnou funkčnost jako webová služba ASMXEmailService, ale místo ASMX využívá WCF. Projekt WCFEmailService si popíšeme dále v této kapitole.
Vytváření webové služby ASMX Projekt ASMXEmailService je projekt webové aplikace ASP.NET, jenž pro služby ASMX využívá IIS. Mohlo by se jednat i o webový server, pro tento příklad je však využit webový server Cassini. Projekt obsahuje jednu webovou službu ASMX s názvem EmailService.asmx. Příklad 5.1 ukazuje obsah třídy EmailService, jež jednoduše definuje metodu webové služby SendMailMessage přijímající požadované informace o zprávě. Webová služba EmailService definuje svůj jmenný prostor jako http://www.silverlight-data.com a přidává atribut WebMethod do metody SendMailMessage. Tento atribut deklaruje, že metoda bude přístupná z klientů, kteří odkazují na webovou službu EmailService. Třída EmailLibrary.Mail je v samostatném projektu, protože bude volána také webovou službou WCF dále v této kapitole.
Příklad 5.1 Třída EmailService C#
using System.Web.Services; using EmailLibrary; namespace ASMXEmailService { [WebService(Namespace = "http://www.silverlight-data.com/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] public class EmailService : System.Web.Services.WebService { [WebMethod] public void SendMailMessage(string from, string to, string subject, string body) { new Mail().SendMessage(from, to, subject, body); } }
Silverlight – datové služby
121
} VB
Imports System.Web.Services Imports EmailLibrary Namespace ASMXEmailService <WebService(Namespace := "http://www.silverlight-data.com/"), _ WebServiceBinding(ConformsTo := WsiProfiles.BasicProfile1_1), _ System.ComponentModel.ToolboxItem(False)> _ Public Class EmailService Inherits System.Web.Services.WebService <WebMethod> _ Public Sub SendMailMessage(ByVal from As String, _ ByVal [to] As String, ByVal subject As String, _ ByVal body As String) CType(New Mail(), Mail).SendMessage(From, [to], subject, body) End Sub End Class End Namespace
Všimněte si, že tento kód vyžaduje, aby byl port SMTP a hostitel příslušně nakonfigurován pro server SMTP, jenž bude použit. Změny na správná nastavení je nutné provést před spuštěním tohoto zkušebního kódu.
Metoda SendMailMessage volá metodu SendMessage třídy EmailLibrary.Mail. Příklad 5.2 ukazuje obsah třídy Mail a její metodu SendMessage, jež odesílá zprávu seznamu příjemců. V kódu chybí zpracování výjimek a určitá propracovanost, na to se však v této kapitole nezaměřujeme. Příklad 5.2 Třída Mail C#
using System; using System.Net.Mail; namespace EmailLibrary { public class Mail { private readonly char[] separator = { ';' }; private readonly string host = "mail.yoursmtpserver.net"; private readonly int port = 25; public void SendMessage(string from, string to, string subject, string body) {
122
Kapitola 5: WCF, webové služby a mezidoménové zásady using (MailMessage message = new MailMessage { From = new MailAddress(from), Body = body, Subject = subject }) { string[] addresses = to.Split(separator, StringSplitOptions.RemoveEmptyEntries); foreach (string t in addresses) message.To.Add(new MailAddress(t)); SmtpClient smtpClient = new SmtpClient(host, port); smtpClient.Send(message); } } }
} VB
Imports System Imports System.Net.Mail Namespace EmailLibrary Public Class Mail Private ReadOnly separator() As Char = { ";"c } Private ReadOnly host As String = "mail.yourmailserver.net" Private ReadOnly port As Integer = 25 Public Sub SendMessage(ByVal from As String, ByVal [to] As String, _ ByVal subject As String, ByVal body As String) Using message As MailMessage = New MailMessage _ With {.From = New MailAddress(From), .Body = body, _ .Subject = subject} Dim addresses() As String = [to].Split(separator, _ StringSplitOptions.RemoveEmptyEntries) For Each t As String In addresses message.To.Add(New MailAddress(t)) Next t Dim smtpClient As New SmtpClient(host, port) smtpClient.Send(message) End Using End Sub End Class End Namespace
To je vše, co je třeba pro vytvoření webové služby ASMX, jíž může využívat aplikace Silverlightu. Dalším krokem je přidání odkazu na službu.
Silverlight – datové služby
123
Odkazování na webovou službu ASMX Než můžete začít službu používat, je nutné přidat do klientské aplikace odkaz na webovou službu ASMX. Přejděte do průzkumníka projektu (Project Explorer), klikněte pravým tlačítkem myši na uzel Service Reference pro projekt SilverlightEmailClient a v místní nabídce zvolte příkaz Add Service Reference. Otevře se okno, v němž lze vyhledat službu dostupnou na počítači. Případně lze zadat adresu URL na konkrétní webovou službu. Protože služba EmailService. asmx je na stejném počítači jako toto řešení, můžete kliknout na tlačítko Discover. Po chvíli klientská aplikace Silverlightu vyhledá službu EmailService.asmx a vy ji můžete vybrat. V tomto okně bude vyhledána jakákoli služba, jež vystavuje jazyk WSDL (Web Services Description Language), díky němuž ji lze najít. Webové služby WCF i ASMX podporují SOAP 1.1 a lze je najít prostřednictvím tohoto okna. Jako odkaz na službu z aplikace Silverlightu lze přidat jakoukoli službu SOAP, kterou lze nalézt, a jež podporuje základní profil SOAP 1.1. Vyhledatelné služby podporují WSDL. Jak si ukážeme v této kapitole, patří sem služby WCF i ASMX. Přístup ke službám, jež se samy nepopisují (jako je například REST, PX a RSS), lze získat prostřednictvím WebClient a HttpWebRequest, což si ukážeme v dalších kapitolách. Všimněte si, že adresa webové služby na obrázku 5.4 ukazuje, že využívá webový server Cassini na portu 8242. Cassini je Vývojový webový server ASP.NET. Vytváříte-li webovou aplikaci s pomocí serveru Cassini, může se číslo portu lišit. ASMXEmailService je webová aplikace, jež běží na serveru Cassini a automaticky přiřazuje porty. Pokud byla služba vytvořena pro webový server, běžela by na IIS a ne na Cassini.
Na obrázku 5.4 je vybraná služba EmailService.asmx a v rozbaleném seznamu jejích služeb a metod je uvedena webová metoda SendMailMessage, která byla právě vytvořena. Služba je přejmenována na ASMXEmailService, což bude jmenný prostor pro třídu proxy, kterou vytvoříme pro vyvolání webové služby ASMX.
Vrácení kolekce ObservableCollection<T> Tlačítko Advanced (v levé dolní části na obrázku 5.4) umožňuje upravit odkaz na webovou službu. Obrázek 5.5 ukazuje, jak lze díky této možnosti upravit typ Collection, který použijeme pro vrácené hodnoty založené na kolekci. To znamená, že pokud webová služba vrátí List<T>, můžete nakonfigurovat odkaz na službu tak, aby byl List<T> automaticky převeden na ObservableCollection<T>. Nakonfigurovat lze několik možností, včetně Array, List, Collection a ObservableCollection. To je důležité, protože se tak usnadňuje využívání služeb, jež vracejí seznamy entit s funkcemi datových vazeb kolekce ObservableCollection.
124
Kapitola 5: WCF, webové služby a mezidoménové zásady
Využívání webové služby ASMX Jakmile má aplikace Silverlightu odkaz na webovou službu ASMX, může ji vyvolat prostřednictvím objektu proxy. Pro vyvolání webové služby je nutné přidat odkaz na službu, vytvořit instanci objektu proxy, přidat obsluhu události pro událost dokončení a asynchronně vyvolat webovou službu.
Obrázek 5.4 Přidání odkazu na e-mailovou službu ASMX
Znovu ty vazby Aplikace Silverlightu obsahuje čtyři ovládací prvky TextBox, jež představují adresu To (komu), adresu From (od), Subject (předmět) a Body (text zprávy). Adresa To může obsahovat sadu e-mailových adres oddělených středníkem. Výchozí hodnoty lze ručně načíst do ovládacích prvků TextBox nastavením jednotlivých hodnot vlastnosti Text prvku TextBox. Poté, co uživatel zadá hodnoty, můžete tyto hodnoty získat z ovládacích prvků TextBox a předat je do webové metody ve webové službě ručním získáním hodnot z ovládacích prvků a odesláním do místních proměnných. Ačkoli tento postup funguje, další možností je využití techniky vazeb založených na XAML. Třída MessageInfo je v kódu příkladu uvedena za účelem uložení hodnot z těchto polí a působí jako prostředník pro ovládací prvky TextBox. Příklad 5.3 ukazuje kód pro třídu MessageInfo. Je vytvořena instance třídy MessageInfo a výchozí hodnoty jsou inicializovány v konstruktoru
Silverlight – datové služby
125
ovládacího prvku EmailClient Silverlightu. Příklad 5.4 ukazuje část kódu XAML ovládacího prvku a jeho vazeb. Příklad 5.3 Třída MessageInfo C#
public class MessageInfo { public string FromAddress { get; set; } public string ToAddress { get; set; } public string Subject { get; set; } public string Body { get; set; } public string BodyWithDateTag { get { return string.Format("{0}\n\nSent on: {1}", this.Body, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); } } }
VB
Public Class MessageInfo Private privateFromAddress As String Public Property FromAddress () As String Get Return privateFromAddress End Get Set(ByVal value As String) privateFromAddress = value End Set End Property Private privateToAddress As String Public Property ToAddress() As String Get Return privateToAddress End Get Set(ByVal value As String) privateToAddress = value End Set End Property Private privateSubject As String Public Property Subject() As String Get Return privateSubject End Get Set(ByVal value As String) privateSubject = value
126
Kapitola 5: WCF, webové služby a mezidoménové zásady End Set End Property Private privateBody As String Public Property Body() As String Get Return privateBody End Get Set(ByVal value As String) privateBody = value End Set End Property Public ReadOnly Property BodyWithDateTag() As String Get Return String.Format("{0}" & Constants.vbLf + Constants.vbLf & _ "Sent on: {1}", Me.Body, _ DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")) End Get End Property
End Class
Jakmile je instance vytvořena, je nastavena na vlastnost DataContext panelu rozložení Grid, jenž obsahuje čtyři ovládací prvky TextBox. Vlastnost Text každého ovládacího prvku TextBox je svázána s odpovídající vlastností instance MessageInfo s využitím vazby TwoWay. Díky tomu není nutné ručně odesílat hodnoty do ovládacích prvků a ručně je z nich získávat. Hodnoty zachytíte nebo nastavíte proměnnou instance messageInfo. Příklad 5.4 XAML pro ovládací prvek Silverlightu EmailClient <TextBox Grid.Row="0" Grid.Column="1" Margin="11,5,45,5" Style="{StaticResource TextBoxStyle}" x:Name="tbFrom" HorizontalAlignment="Stretch" Text="{Binding Mode=TwoWay, Path=FromAddress}"/> <TextBox Grid.Row="1" Grid.Column="1" Margin="11,5,45,5" Style="{StaticResource TextBoxStyle}" x:Name="tbTo" HorizontalAlignment="Stretch" Text="{Binding Mode=TwoWay, Path=ToAddress}"/> <TextBox Grid.Row="2" Grid.Column="1" Margin="11,5,45,5" Style="{StaticResource TextBoxStyle}" x:Name="tbSubject" HorizontalAlignment="Stretch" Text="{Binding Mode=TwoWay, Path=Subject}"/> <TextBox Grid.Row="3" Grid.Column="1" Margin="11,5,45,5"
Silverlight – datové služby
127
Style="{StaticResource TextBoxStyle}" x:Name="tbBody" HorizontalAlignment="Stretch" VerticalAlignment="Top" Height="100" VerticalScrollBarVisibility="Visible" AcceptsReturn="True" TextWrapping="Wrap" Text="{Binding Mode=TwoWay, Path=Body}"/>
Třída MessageInfo obsahuje veřejnou vlastnost pouze pro čtení s názvem BodyWithDateTag, jež neodkazuje přímo na pomocnou vlastnost. Vlastnost BodyWithDathDateTag teTag vrátí vlastnost zprávy Body spolu s datem a časovým razítkem, především pro účely ladění.
Obrázek 5.5 Nastavení odkazu na službu
Konstruktor EmailClient (viz příklad 5.5) také přidává obsluhu události Click pro prvek Button s názvem btnSendViaASMX. Metoda btnSendViaASMX obsluhuje událost kliknutí, když je uživatel připraven odeslat zprávu. Tato metoda vytvoří proxy a bude volat webovou službu.
Kapitola 9 Vytváření služeb RESTful a využívání aplikace SilverTwit
V předcházející kapitole jste se dozvěděli, jak lze využívat výhody služeb RESTful v rozhraní API webových služeb Amazon při vytváření klientské aplikace Silverlightu 2, jež bude uživateli umožňovat vyhledávání a nakupování na webu Amazon.com. Na případové studii jsme si ukázali, jak lze požadovat data pomocí metody HTTP GET, ale existují samozřejmě i další způsoby vystavování dat pomocí HTTP přes metody POST, PUT, DELETE a další metody HTTP. V této kapitole zmíněná témata dále rozšíříme a ukážeme si, jak lze vytvářet uživatelské webové služby REST pomocí Windows Communication Foundation (WCF), podporovat akce HTTP, upravovat šablony URI a vracet data ve formátu XML nebo JSON. Navrhujete-li webové služby za účelem vystavení funkcí a zdrojů klientským aplikacím, jsou webové služby RESTful v mnoha případech dobrou alternativou k využívání služeb založených na SOAP. Vlastní služby RESTful lze vytvářet různými způsoby; WCF však nabízí mnoho možností potřebných k vytvoření služby RESTful. V této kapitole se dozvíte, jak lze pomocí WCF vytvářet vlastní služby RESTful, jež budou odesílat a přijímat požadavky a odpovědi. Seznámíte se také s různými metodami HTTP a naučíte se, jak implementovat stavové kódy a definovat šablony URI. Službu RESTful lze navrhovat tak, aby se data vracela v různých formátech. Běžnými datovými formáty jsou XML a JSON. V této kapitole se dozvíte, jak navrhovat služby, jež odesílají odpovědi ve formátu JSON nebo XML, a uvidíte, jak lze odpověď zpracovávat pomocí nástrojů, jako je LINQ to XML, LINQ to JSON a DataContractJsonSerializer. Jednotlivá témata si představíme v jednoduchých příkladech, v nichž budeme vytvářet aplikace Silverlightu 2 volající vlastní webové služby WCF RESTful. Tyto příklady vás provedou vytvářením klienta Silverlightu Twitter, jenž čte a posílá zprávy z Twitter API RESTful pomocí HTTP s využitím akcí GET a POST. Příklad navazuje na témata, s nimiž jste se v této knize již setkali při vytváření klienta Silverlightu, vytváření služby RESTful navržené pomocí WCF, řešení problémů při komunikaci mezi doménami a LINQ. V této kapi-
242
Kapitola 9: Vytváření služeb RESTful a využívání aplikace SilverTwit
tole se zaměříme na kód na straně serveru (služby RESTful) a na straně klienta (pro využívání služeb).
Vytvoření služeb RESTful pomocí WCF V kapitole 7 jsme probírali strukturu služby RESTful, jedinečný identifikátor URI a služby řízené zdroji. V této části si ukážeme, jak lze pomocí WCF vytvořit službu RESTful, kterou může Silverlight využívat. Před vytvořením služby RESTful je důležité zvážit rozdíly mezi charakteristickými rysy služby RESTful a webovou službou vytvořenou na základě SOAP. Obecně se služby WCF zaměřují na provádění akcí, jako je získávání seznamu produktů (FindProducts()), přidávání zákazníků (AddCustomer(Customer cust)) nebo vyhledávání objednávek (FindOrders(int year)). Někteří vývojáři berou tyto typy služeb jako slovesa, protože jsou založeny na akcích. Webové služby založené na REST se obecně zaměřují na zdroj a ne na akci; služby založené na REST si lze představit jako služby, jež se točí kolem podstatných jmen (zdrojů). Zatímco ve WCF může být metoda služby FindProducts(), v operaci webové služby REST by identifikátor URI mohl být voláním metody HTTP GET na http://silverlight-data.com/MyService.svc/Product. Ačkoli metoda služby WCF může být AddCustomer(Customer cust), služba RESTful může využívat metodu HTTP POST na URI http://silverlight-data.com/MyService.svc/ Customer. Styly těchto služeb se jasně liší jak v implementaci, tak v návrhu. Při využití druhého stylu musí vývojář více přemýšlet o práci se zdroji, zatímco u prvního stylu jde o akci, jež má být provedena.
Vytváření služby RESTful Chcete-li vytvořit webovou službu RESTful pomocí WCF při využití IIS nebo Windows Process Activation Service (WPAS), proveďte následující kroky: 1. Vytvořte soubor RESTfulService.svc v kořeni projektu. 2. Vytvořte soubor s kódem RESTfulService.cs. 3. Nakonfigurujte službu RESTful v souboru *.config nebo ve vlastním souboru .svc. Volitelně lze vytvořit rozhraní IRESTfulService.cs. 4. Definujte vlastnosti jednotlivých operací. Prvním krokem při vytváření služby RESTful pomocí WCF je přidání nového souboru služby WCF do projektu. Ve zkušebním kódu je využit projekt webové aplikace hostící webové služby RESTful WCF. Službu WCF lze vytvořit pomocí šablony služby WCF nebo prostřednictvím šablony Silverlight-enabled WCF Service. Bez ohledu na zvolenou šablonu je nutné upravit konfiguraci služby tak, aby podporovala službu RESTful.
Silverlight – datové služby
243
Vytváření rozhraní služby Kód ve zkušební aplikaci vytvořil službu WCF pomocí šablony služby WCF. Tato služba s názvem RESTfulService.svc implicitně definuje své kontrakty služby a operace v souboru RESTfulService.cs. Službu a kontrakty operací lze případně přesunout do rozhraní. Definování rozhraní je volitelný úkon, jenž umožňuje veřejně vystavovat metody webové služby, přičemž služby jsou definovány stručně a jasně na jednom místě. Metody webové služby (rovněž označované jako operace) definujete v rozhraní spolu s atributy, jež určují charakteristické rysy (například šablona URI a akce HTTP) každé operace. Ve zkušebním kódu je služba implementována ve třídě RESTfulService, jež implementuje rozhraní s názvem IRESTfulService. Rozhraní IRESTfulService definuje kontrakt služby a operace.
Konfigurace služby RESTful Konfigurace webové služby WCF podporující REST vyžaduje jiné aspekty, než webové služby WCF podporující SOAP. Služba RESTful nemusí zveřejňovat svá metadata, a proto není nutné vytvářet specifické chování služby. To znamená, že lze v konfiguračním souboru vynechat podřízený prvek serviceBehaviors v system.serviceModel služby REST. Služby založené na SOAP, jež jsou využívané aplikacemi Silverlightu, musí využívat vazbu basicHttpBinding. Naproti tomu webové služby WCF REST využívají vazbu webHttpBinding. Pro služby vystavované pomocí webHttpBinding nejsou zveřejňována žádná metadata, a proto nepotřebujete část serviceBehavior pro služby REST. Ačkoli nepotřebujete část serviceBehavior, webová služba REST vyžaduje režim práce koncového bodu. V příkladu 9.1 vidíte správné uspořádání webové služby WCF RESTful, včetně nastavení webHttp v chování koncového bodu s názvem webBehavior. Celou sadu kódů pro všechny příklady v této kapitole naleznete v řešení RESTfulClient, jež se nachází ve složce s kódem pro tuto kapitolu.
Příklad 9.1 Konfigurace RESTful <system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="webBehavior"> <webHttp/> </behavior> </endpointBehaviors> </behaviors> <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> <services> <service name="RESTfulServices.RESTfulService"> <endpoint address="" behaviorConfiguration="webBehavior"
244
Kapitola 9: Vytváření služeb RESTful a využívání aplikace SilverTwit binding="webHttpBinding" bindingConfiguration="" contract="RESTfulServices.IRESTfulService"/> </service> </services>
</system.serviceModel>
Část service v konfiguraci definuje název služby a její podřízený prvek endpoint definuje podrobné informace o koncovém bodu webové služby RESTful. Atribut name prvku service představuje úplný název implementované služby. Atribut address je v příkladu 9.1 ponechán prázdný. To znamená, že koncový bod bude použit v případě, že identifikátor URI odkazuje do kořene služby. Definujete-li více koncových bodů – například jeden pro službu RESTful a další pro službu SOAP – lze je rozlišit pomocí atributu address. Pro koncový bod RESTful lze například nastavit adresu rest a koncový bod SOAP může mít nastavenou adresu soap. Díky tomu byste mohli volat oba typy služeb jednoduše přidáním jedné z těchto adres do identifikátoru URI. Například následující URI odkazuje na webovou službu REST: http://silverlight-data.com/MyService.svc/rest/ Tento odkaz sleduje webovou službu SOAP: http://silverlight-data.com/MyService.svc/soap/ Atribut behaviorConfiguration odkazuje na režim koncového bodu webBehavior. V tomto případě to umožňuje službě podporovat charakteristické rysy REST. Pro tento koncový bod REST není nutné provádět žádnou konfiguraci vazby. Atribut contract odkazuje na název třídy nebo rozhraní definující kontrakt služby. V tomto příkladu je kontraktem rozhraní s názvem IRESTfulService. Využijete-li k vytvoření služby šablonu Silverlight-enabled WCF Service, nevytvoří tato šablona rozhraní. Pokud rozhraní přidáte, případně upravíte kód (jako v tomto příkladu), je nezbytné změnit název kontraktu v konfiguraci tak, aby odkazoval na rozhraní a nikoli na třídu. Ve své podstatě musí být kontrakt názvem objektu, jenž má atribut ServiceContract. Posledním atributem koncového bodu je vazba. Služba WCF implicitně využívá režim vazeb wsHttpBinding, který nemohou využívat klienti Silverlightu. Využijete-li šablonu Silverlight-enabled WCF Service, implicitně se nastaví režim vazeb basicHttpBinding. Při vytváření a využívání služby WCF založené na SOAP (v tomto případě aplikací Silverlightu) nastavíte režim vazeb na basicHttpBinding. Žádné z těchto nastavení vazeb nepodporuje služby RESTful, proto je nastaven režim vazeb webHttpBinding.
Definování kontraktu Poté, co jste vytvořili a nakonfigurovali webovou službu WCF RESTful, jež je připravena k využívání, je nutné vystavit jednotlivé operace, které bude služba vykonávat. Tyto operace mají
Silverlight – datové služby
245
atribut OperationContract ve jmenném prostoru System.ServiceModel a nacházejí se v rozhraní IRESTfulService. Ke každé operaci REST lze přidat další atribut. Jmenný prostor System.ServiceModel.Web obsahuje atributy WebGet a WebInvoke. Tyto atributy deklarují, že operace webové služby podporuje jednu z metod HTTP, jako GET, POST, PUT nebo DELETE. Nemá-li operace kontraktu služby atribut WebGet nebo WebInvoke, využije se implicitně metoda POST, přičemž UriTemplate představuje název operace. V praxi se však osvědčilo přidávat ke všem operacím atribut WebGet nebo WebInvoke. Před přidáním atributů WebGet a WebInvoke musí projekt odkazovat na sestavení System.ServiceModel.Web.dll.
Na obrázku 9.1 vidíte několik charakteristických rysů služby webové operace REST, jež lze nastavit, včetně atributů WebGet či WebInvoke. Atribut WebGet indikuje, že bude proveden požadavek HTTP GET a lze požadovat odpověď. Atribut WebInvoke určuje, že bude provedena metoda HTTP GET, POST, PUT nebo DELETE. Ačkoli služby RESTful vytvořené pomocí WCF podporují metody PUT a DELETE, Silverlight může využívat pouze metody HTTP GET nebo HTTP POST pomocí třídy WebClient nebo HttpWebRequest. Silverlight však může využívat metody PUT nebo DELETE prostřednictvím rozhraní Javascript API a voláním přes objekt XmlHttpRequest. GET (WebGet)
Metoda HTTP
UriTemplate
Styly parametrů
Formát odpovědi
POST (WebInvoke)
Jedinečný identifikátor URI
Samostatný segment Výchozí hodnota
JSON XML
Styl textu
Prostý Zabalený
Stavové kódy HTTP
Obrázek 9.1 Návrh služby RESTful
246
Kapitola 9: Vytváření služeb RESTful a využívání aplikace SilverTwit
Příklad 9.2 ukazuje kontrakt služby a první operaci pro rozhraní IRESTfulService. UriTemplate v příkladu 9.2 indikuje, že kombinace cesty služby a UriTemplate vytvoří jedinečnou ces-
tu, jež vyvolá operaci FindProduct1. Služba je hostována na adrese http://localhost/RESTfulServices/RESTfulService.svc. Úplná cesta pro vyvolání této operace a předání hodnoty pro parametr productIdString zní http://localhost/RESTfulServices/RESTfulService.svc/Product/1001. Atributy WebGet indikují, že bude proveden požadavek HTTP GET. UriTemplate definuje, že ve zdroji Product bude dotazován určitý identifikátor produktu. ResponseFormat určuje, že odpověď bude odeslána zpět klientovi ve formátu XML a BodyStyle definuje, že požadavek a odpověď budou v prostém textu a nebudou zabaleny. V případě potřeby lze požadavky a odpovědi zabalit do kontejnerového prvku. V následujících příkladech není nutné požadavky a odpovědi zabalit, proto jsou označeny jako Bare. Zabalené požadavky a odpovědi jsou ideální v případě, kdy obsah zprávy vyžaduje kontejnerový prvek. Například zpráva odpovědi může být částí XML bez kořenového prvku. Použijete-li WebMessageBodyStyle.Wrapped, může být část XML automaticky zabalena s vnějším prvkem XML. Příklad 9.2 Kontrakt služby a operace C#
[ServiceContract(Namespace = "http://www.silverlight-data.com")] public interface IRESTfulService { // #1 [OperationContract] [WebGet(UriTemplate = "Product/{productIdString}", ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)] Product FindProduct1(string productIdString); // Zde jsou definované další kontrakty ... }
VB
<ServiceContract(Namespace := "http://www.silverlight-data.com")> _ Public Interface IRESTfulService ' #1 <OperationContract, WebGet(UriTemplate := "Product/{productIdString}", _ ResponseFormat := WebMessageFormat.Xml, _ BodyStyle := WebMessageBodyStyle.Bare)> _ Function FindProduct1(ByVal productIdString As String) As Product ' Zde jsou definované další kontrakty ... End Interface
Implementace metody FindProduct1 v příkladu 9.3 ukazuje, že parametr v UriTemplate se shoduje s názvem v metodě FindProduct1. Každý parametr definovaný v UriTemplate je nutné
Silverlight – datové služby
247
uzavřít do složených závorek a parametr se musí shodovat s názvem parametru v metodě. Je-li parametr součástí cesty URI, musí se jednat o řetězec string. Je-li parametr součástí dotazovacího řetězce, je podporován základní typ konverze. Protože vlastnost ProductId třídy Product je celé číslo, je nejprve nutné převést parametr productIdString na celé číslo tak, jak to vidíte v příkladu 9.3. Parametr lze rovněž definovat jako součást složeného segmentu; ve složeném segmentu existuje cesta a parametr ve stejném segmentu URI. Například UriTemplate z Product({productIdString}) obsahuje složený segment, přičemž parametr (uvnitř závorek) je předáván ve stejném segmentu, jako Product. Příklad by mohl vypadat takto: /somepath/some.svc/Product(123)
Po získání příslušného produktu pomocí LINQ to Object do metody FindProduct1, vrátí se Product do klienta prostřednictvím Response. Protože ResponseFormat je nastaven na WebMessageFormat.Xml, je Product před odesláním zpět v rámci Response převeden do XML. Před příchodem verze .NET SP1 bylo nutné přidávat do třídy a jejích vlastností atributy DataMember a DataContract. Chcete-li do procesu serializace přidat nebo z něj vyloučit určité vlastnosti, lze počínaje verzí .NET SP1 přidávat ke třídě Product atribut DataContract a k jejím vlastnostem atribut DataMember. Příklad 9.3 Jednoduchý požadavek GET na produkt C#
public Product FindProduct1(string productIdString) { int productId = int.Parse(productIdString); List<Product> products = GetProductList(); var query = from p in products where p.ProductId == productId select p; Product product = query.FirstOrDefault() as Product; return product; }
VB
Public Function FindProduct1(ByVal productIdString As String) As Product Dim productId As Integer = Integer.Parse(productIdString) Dim products As List(Of Product) = GetProductList() Dim query = _ From p In products _ Where p.ProductId = productId _ Select p Dim product As Product = TryCast(query.FirstOrDefault(), Product) Return product End Function
248
Kapitola 9: Vytváření služeb RESTful a využívání aplikace SilverTwit
Využívání služeb REST Poté, co definujete službu, lze nastavit klienta, jenž bude tuto službu využívat. Klientská aplikace Silverlightu s názvem RESTfulClient (viz obrázek 9.2) ve zkušebním kódu volá službu RESTful (viz obrázek 9.3) pomocí třídy WebClient a jedinečného identifikátoru URI, jenž odpovídá operaci FindProduct1. Aplikace zobrazí seznam operací, jež volají různé metody webové služby z projektu RESTfulService. Příklad 9.4 ukazuje, jak klientská aplikace Silverlightu využívá metodu webové služby FindProduct1. Každá metoda volání má v komentářích stejné číslo, jako odpovídající metoda webové služby. Díky tomu lze lépe rozpoznat, které metody volají jednotlivé metody webové služby.
Příklad 9.4 Volání služby RESTful z aplikace Silverlightu C#
private readonly string _domain = "localhost:9726"; public string BaseUri { get { return string.Format("http://{0}/RESTfulService.svc", _domain); } } private void GetProductAsync_AsXml_IdInSegment() { WebClient wc = new WebClient(); wc.DownloadStringCompleted += ParseProducts_AsXml; int productId = 1001; string urlString = string.Format("{0}/Product/{1}", BaseUri, productId); Uri uri = new Uri(urlString); wc.DownloadStringAsync(uri); }
VB
Private ReadOnly _domain As String = "localhost:9726" Public ReadOnly Property BaseUri() As String Get Return String.Format("http://{0}/RESTfulService.svc", _domain) End Get End Property Private Sub GetProductAsync_AsXml_IdInSegment() Dim wc As New WebClient() wc.DownloadStringCompleted += ParseProducts_AsXml Dim productId As Integer = 1001
Silverlight – datové služby
249
Dim urlString As String = String.Format("{0}/Product/{1}", BaseUri, productId) Dim uri As New Uri(urlString) wc.DownloadStringAsync(uri) End Sub
Metoda ParseProducts_AsXml obsluhuje událost DownloadStringCompleted pro metody ve zkušebním kódu, jež získávají jeden či více produktů ve formátu XML. Parsuje kód XML tak, aby byly nalezeny hodnoty vlastností ProductId, UnitPrice a ProductName a pro každou z nich vytváří instanci třídy Product. Metody ToInt a ToDecimal jsou rozšiřující metody třídy string, jež jednoduše parsuje hodnotu řetězce na celé nebo desetinné číslo. Jsou definovány ve třídě ConversionExtensions v projektu RESTfulClient. Tato definice dotazu LINQ to Query funguje, ať již webová služba vrací jeden či více produktů.
Obrázek 9.2 Získání produktu z webové služby RESTful
Klientská aplikace Silverlightu se nachází v jiné doméně než webová služba (jako u skutečných aplikací). Protože se jedná o mezidoménový požadavek, je nutné umístit do kořene webu soubor s mezidoménovými zásadami, jenž umožňuje přístup ke službám. Zkušební kód pro tuto kapitolu obsahuje kopii souboru clientaccesspolicy.xml v kořeni domény. V příkladu 9.5 vidíte, jak klientská aplikace Silverlightu parsuje XML odpovědi pomocí LINQ to XML. Příklad 9.5 Parsování odpovědí pomocí LINQ to XML C#
private void ParseProducts_AsXml(object sender, DownloadStringCompletedEventArgs e) { string ns = ""; string rawXml = e.Result;
250
Kapitola 9: Vytváření služeb RESTful a využívání aplikace SilverTwit XDocument xdoc = XDocument.Parse(rawXml); var query = from product in xdoc.Descendants(ns + "Product") select new Product { ProductId = product.Element("ProductId").Value.ToInt(), ProductName = product.Element("ProductName").Value, UnitPrice = product.Element("UnitPrice").Value.ToDecimal() }; List<Product> products = query.ToList() as List<Product>; lstProducts.DataContext = products;
} VB
Private Sub ParseProducts_AsXml(ByVal sender As Object, _ ByVal e As DownloadStringCompletedEventArgs) Dim ns As String = "" Dim rawXml As String = e.Result Dim xdoc As XDocument = XDocument.Parse(rawXml) Dim query = _ From product In xdoc.Descendants(ns & "Product") _ Select New Product With _ { _ .ProductId = product.Element("ProductId").Value.ToInt(), _ .ProductName = product.Element("ProductName").Value, _ .UnitPrice = product.Element("UnitPrice").Value.ToDecimal() _ } Dim products As List(Of Product) = TryCast(query.ToList(), List(Of Product)) lstProducts.DataContext = products End Sub
Výchozí hodnoty V příkladu 9.6 vidíte, jak lze upravit identifikátor URI, aby parametr productIdString mohl mít výchozí hodnotu. Je-li vyvolán URI shodující se s UriTemplate, jenž vynechává parametr productIdString, bude tomuto požadavku odpovídat následující operace UriTemplate. Příklad 9.6 Upravená šablona URI ve službě C#
// #2 [OperationContract] [WebGet(UriTemplate = "Product2/{productIdString=1011}", ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)] Product FindProduct2(string productIdString);
VB
' #2
Silverlight – datové služby
251
<OperationContract, _ WebGet(UriTemplate := "Product2/{productIdString=1011}", _ ResponseFormat := WebMessageFormat.Xml, _ BodyStyle := WebMessageBodyStyle.Bare)> _ Product FindProduct2(String productIdString)
Kód pro metodu FindProduct2 je stejný jako je kód pro FindProduct1 (viz příklad 9.3). Instance Product je převedena do XML a poslána zpět klientovi Silverlightu v Response, kde je parsována pomocí LINQ to XML v metodě ParseProducts_AsXml (viz příklad 9.5). Výsledky jsou pak svázány do ListBox a zobrazí se uživateli.
Stavové kódy HTTP Stavové kódy umožňují informovat o stavu operace, jež je vyvolána aplikací přes HTTP. Při vývoji webových služeb RESTful je vhodné vracet po dokončení operace stavové kódy HTTP. Stavové kódy HTTP mohou signalizovat úspěšný průběh i hlásit chyby operací webové služby. Obsahuje-li například parametr neočekávanou hodnotu, lze nastavit stavový kód HTTP na hodnotu enumerátoru HttpStatusCode.BadRequest, jež je převedena na stav HTTP 400. Pokud metoda nalezne produkt a úspěšně jej vrátí, lze nastavit stavový kód HTTP na HttpStatusCode.OK, což vrátí stav HTTP 200. K výchozím stavovým kódům patří 200 (OK) a 500 (Vnitřní chyba serveru). Nedojde-li v metodě k žádné výjimce a v metodě není explicitně nastaven žádný stavový kód, vrátí se stavový kód 200. Pokud dojde k výjimce a není nastaven žádný stavový kód, vrátí se stavový kód 500. Výčet HttpStatusCode naleznete ve jmenném prostoru System.Net. Kódy mapují přímo do standardních stavových kódů HTTP, jako je 400 pro bad request, 404 pro not found a 201 pro created. Kód v příkladu 9.7 vyhledá produkt a nastaví stavový kód HTTP na příslušnou hodnotu enumerátoru. Tyto hodnoty lze rozpoznat, spustíte-li službu pomocí nástroje, jako je například Fiddler2 (viz obrázek 9.3).
Obrázek 9.3 Stav HTTP 200
Příklad 9.7 Přiřazování stavových kódů HTTP C#
// # 3 public Product FindProduct3(string productIdString) { if (productIdString.Length == 0) { WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.BadRequest;