Redazione
a- a+

Accesso ai dati

Silverlight: accesso ai dati

Serializzazione

In un tipico scenario di comunicazione fra due macchine inRete, il client e il server si passano rispettivamente deimessaggi di richiesta e di risposta in formato testuale.Tutti gli elementi trasportati in Rete vengono primaconvertiti in testo (questo vale anche per i datimultimediali), trasportati al client per poi venir ricreatidal testo per ottenere nuovamente il loro formato originale.Il processo di conversione di un oggetto complesso nella suarappresentazione testuale viene chiamato serializzazione,mentre il processo inverso viene definito deserializzazione.

I formati più comuni utilizzati per trasportare datinel Web sono XML XML, SOAP e JSON. Il .NET Framework latoserver e quello incluso in Silverlight hanno entrambi lapossibilità di serializzare e deserializzare i dati.

Accesso ai dati

Bisogna ricordarsi che tipicamente i dati memorizzati in undatabase risiedono su un server remoto menteun'applicazione Silverlight risiede sulla macchina latoclient. Per recuperare tali dati remoti quindi, la richiestadev'essere inoltrata al server, proprio come per ognialtra applicazione Web. In quest'articolo discuteremo ivari modi per accedere ai dati in Silverlight.

Memorizzazione isolata

Per via di restrizioni di sicurezza per un'applicazioneSilverlight (la famosa "sandbox" in cuiopera), un'applicazione Silverlight non puòleggere files dalla macchina del client a meno che non sianomemorizzati in maniera isolata. Quindi, un'applicazioneSilverlight è piuttosto limitata nelle suecapacità per memorizzare i dati localmente, ad ognimodo dei semplici files possono essere creati per memorizzaresemplici dati e settaggi.

I file XML possono essere creati con un'applicazioneSilverlight, ma devono avere la loro azione settata aEmbedded Resource in modo tale che quandol'applicazione viene generata, i file XML vengonocompilati in assembly. Questo limita la possibilità dimodificare i file e che questi possano contenere datidinamici condivisi con altri utenti dell'applicazione.

Silverlight include classi per lavorare con XML, ad ogni modoqueste classi sono concepite per leggere una stringa XML inentrata (come quella proveniente da una chiamata ad un Webservice) e non per leggere file XML.

Accedere ai dati usando SOA

Come descritto in precedenti articoli, un'applicazioneSilverlight può effettuare delle chiamate ad un Webservice. Tali chiamate possono trasportare dati usando puroXML (POX - Plain Old XML) o JSON. Inoltre un Webservice invocato da un'applicazione Silverlight deverisiedere nello stesso dominio dell'applicazione, comeprecauzione di sicurezza e in quanto tale, limita da un latole possibilità di Silverlight ma dall'altro nonlimita cosa può fare un Web service richiamato dalleapplicazioni. Un Web service richiamato da Silverlight agiscecome un proxy per l'applicazione Silverlight e puòchiamare qualsiasi risorsa per conto dell'applicazione eritornare i risultati. Ad esempio un'applicazioneSilverlight può invocare un Web service che risiedesullo stesso dominio dell'applicazione e questo servizioa sua volta potrebbe richiamare un altro Web service fuoridal dominio dell'applicazione oppure potrebbe eseguiredelle query ad un database. Questi metodi rappresentano lemodalità standard per un'applicazione Silverlightdi recuperare le risorse dei server.

Il servizio che un'applicazione Silverlight richiamapuò assumere la forma di un Web service ASP.NET o unservizio WCF. Come è stato visto in articoli passati,il progetto ASP.NET Futures è stato concepitoesattamente per testare il servizio che può essereredirezionato per trasportare dati attraverso JSON. Ilseguente metodo Web viene usato per connettersi a un databaseSQL Server e ritorna risultati in un ArrayList. Un ArrayListpuò essere ridimensionato dinamicamente ed èserializzabile. Il valore più evidente ritornato da unmetodo Web che ritorna risultati da un database è unDataSet ADO.NET. Ad ogni modo i DataSet non sono supportatial momento per cui un ArrayList sarà sufficiente.

Es 1.1: PetService.cs

using System;  using System.Data;  using System.Data.SqlClient;  using System.Collections.Generic;  using System.Configuration;  using System.Web;  using System.Web.Configuration;  using System.Web.Services;  using System.Web.Services.Protocols;  using System.Xml.Linq;    /// <summary>  /// Descrizione di PetService  /// </summary>  [WebService(Namespace = "http://tempuri.org/")]  [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  [System.Web.Script.Services.ScriptService]  public class PetService : System.Web.Services.WebService {  public PetService () {// Scommentare questa linea se si usano componenti disegnati// InitializeComponent(); }  [WebMethod]public List<string> GetPetInfo() {    // Connect to the database.  using (SqlConnection cn =    new SqlConnection(ConfigurationManager.ConnectionStrings["SQLExpress"].ConnectionString))  {// Query the pet information.    using (SqlCommand cmd = new SqlCommand("Select Name, Breed, Gender, Weight, Notes From Pets" , cn))  {  cn.Open();List<string> petInfo = new List<string>();SqlDataReader rdr = cmd.ExecuteReader();  while (rdr.Read()) {    petInfo.Add("My pet is named " + rdr["Name"].ToString() +     ". It is a " + (rdr["Gender"].ToString() == "True" ? "male" : "female") +    " " + rdr["Breed"].ToString() + " that weighs " + rdr["Weight"].ToString() +    " pounds. " + rdr["Notes"] + " ");}  rdr = null;return petInfo;    }  }} }

 

<a href="/img/11/iframe_accData1.html" title="Vedi esempio">Vedi esempio</a>;

 

Poi, l'applicazione Silverlight può essereaggiunta allo stesso progetto del Web service cheverrà invocato. questo ci assicura che sial'applicazione Silverlight, sia il Web service risiedanonello stesso dominio e siano facilmente testabiliall'interno di Visual Studio 2008. La figura seguentemostra un file XAML sviluppato per ottenere delleinformazioni dal metodo Web visto all'esempio 1.1 emostra i risultati in un TextBlock.

Si può aggiungere un riferimento Weball'applicazione Silverlight per riferire il Web service.Una volta completato, la regione Get Pet Informationè cliccabile per scatenare il gestore degli eventi cheinvoca il Web service e mostra i risultati nella TextBlock.Il seguente listato XAML viene usato per generare la paginavista in precedenza.

Es 1.2: Page.xaml

<Canvas    xmlns="http://schemas.microsoft.com/client/2007"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     x:Name="parentCanvas"     Loaded="Page_Loaded"     x:Class="PetInformationClient.Page;assembly=ClientBin/PetInformationClient.dll"    Width="560"    Height="320">     <Canvas.Background>    <LinearGradientBrush EndPoint="0.498,-0.375" StartPoint="0.502,1.375">     <GradientStop Color="#FFFFFFFF" Offset="0"/>     <GradientStop Color="#FFA3A535" Offset="1"/>    </LinearGradientBrush>   </Canvas.Background>   <Path Width="513" Height="1" Fill="#FFFFFFFF" Stretch="Fill"   Stroke="#FF000000" StrokeThickness="0.5" Canvas.Left="23.5"   Canvas.Top="39.5" Data="M24,40 L536,40"/>     <TextBlock Width="512" Height="232" Canvas.Left="24" Canvas.Top="56"    TextWrapping="Wrap"><Run FontFamily="Segoe UI" FontSize="12"    FontWeight="Normal" x:Name="tbOutput"/>     </TextBlock>   <Canvas Cursor="Hand" Width="178" Height="24.5" Canvas.Left="23.5"     Canvas.Top="11.5" x:Name="canvasGetPetInfo" MouseLeftButtonUp="GetPetInfo">    <Rectangle Width="168.5" Height="24" Stroke="#FFD4A524"   StrokeThickness="1" RadiusX="4" RadiusY="4">     <Rectangle.Fill><LinearGradientBrush EndPoint="0.505,4.01" StartPoint="0.495,-3.01"> <GradientStop Color="#FF000000" Offset="0.301"/> <GradientStop Color="#00FFFFFF" Offset="0.737"/></LinearGradientBrush>     </Rectangle.Fill>    </Rectangle>    <TextBlock Width="168.5" Height="24" TextWrapping="Wrap"   Canvas.Left="9.5" Canvas.Top="0.5"><Run FontFamily="Segoe UI"   FontSize="16" Text="Get Pet Information"/>    </TextBlock>   </Canvas>    </Canvas>

 

<a href="/img/11/iframe_accData2.html" title="Vedi esempio">Vedi esempio</a>;

 

Infine, il gestore degli eventi per la canvas che richiama ilWeb service viene mostrato nel codice sottostante.

Es 1.3: Page.xaml.cs

using System;  using System.Collections.Generic;  using System.Windows;  using System.Windows.Controls;  using System.Windows.Documents;  using System.Windows.Ink;  using System.Windows.Input;  using System.Windows.Media;  using System.Windows.Media.Animation;  using System.Windows.Shapes;    namespace PetInformationClient  {    public partial class Page : Canvas    {public void Page_Loaded(object o, EventArgs e) {  // Richiesto per inizializzare le variabili  InitializeComponent();}    public void GetPetInfo(object o, MouseEventArgs e)  {    PetInformationClient.localhost.PetService svc = new PetInformationClient.localhost.PetService();  string[] petInfo = svc.GetPetInfo();    // mostra i risultati  for (int i = 0; i < petInfo.Length; i++) {tbOutput.Text += petInfo[i].ToString();  }     }    }  }

 

<a href="/img/11/iframe_accData3.html" title="Vedi esempio">Vedi esempio</a>;

 

Il passo successivo per testare il Web servicedall'applicazione Silverlight è aggiungere ilcollegamento Silverlight al progetto ASP.NET Futures e poiaggiungere l'elemento asp:Xaml nella paginadi test Default.aspx. Premete F5 e testatel'applicazione. Dovreste ottenere i risultati riportatiin figura.

 

Language Integrated Query (LINQ)

Un'aggiunta importante al .NET Framework nella versione3.5 è Language Integrated Query (LINQ). La maggiorparte degli sviluppatori avrà familiarità conSQL,linguaggio utilizzato per interrogare i database relazionali.Ad ogni modo nella maggior parte dei casi le query SQL cheprelevani i dati da uno schema di un database relazionalesono astratte rispetto alla logica e al codice middle-tier.Inoltre, i dati sono generalmente rappresentati a livellologico e di codice attraverso oggetti, array e collezioni.Gli sviluppatori devono regolarmente leggere i contenuti diquesti costrutti usando dei cicli.

Ad ogni modo, Microsoft era determinata a render piùfacile la vita dei programmatori creando uno standard perinterrogare i dati memorizzati nei costrutti del codice. Irisultati dei loro sforzi hanno prodotto un nuovo linguaggio,LINQ, mirato ai dati memorizzati negli oggetti e nellecollezioni. LINQ è stato inoltre esteso per esser ingrado di interrogare i classici database relazionali,documenti XML e altre sorgenti di dati. Ad ogni modo i datirecuperati dalle interrogazioni mediante LINQ devono esserememorizzati in oggetti.

LINQ è n grado di interrogare qualsiasi oggetti cheimplementi l'interfaccia Enumerable. LINQpresenterà un nuovo paradigma di programmazione aiprogammatori .NET esperti ma la nuova funzionalità e ibenefici che se ne traggono dovrebbero essere recepitifacilmente dai più.

Come esempio di implementazione LINQ, creeremo lo stessoesempio usato in precedenza ma utilizzando LINQ nel Webservice per accedere ai dati memorizzati in SQL Server cosicome per il codice che sta dietro l'applicazioneSilverlight per iterare i risultati.

Il primo passo per creare una versione del Web service cheutilizza LINQ per accedere ai dati memorizzati in SQL Server2005 è creare un nuovo sito web ASP.NET Futures,aggiungere un nuovo Web service al progetto e aggiungere unanuova classe LING to SQL al progetto come mostrato nellaseguente figura. Tale classe ha un'estensione.dbml (database modeling language).

Una volta che la classe è stata aggiunta, si possonocreare classi di dati spostando le tabelle da Server Explorerall'area di disegno delle classi. La figura sottostantemostra la classe con la tabella Pets che viene aggiuntanell'area disegno.

La versione semplificata del metodo web che utilizza LINQ perrecuperare le informazioni da SQL Server 2005 viene mostrataqui di seguito.

Es 2.1: PetService.cs

using System;using System.Collections;  using System.Linq;  using System.Web;  using System.Web.Services;  using System.Web.Services.Protocols;  using System.Xml.Linq;  using System.Collections.Generic;    /// <summary>  /// Descrizione di PetService  /// </summary>    [WebService(Namespace = "http://tempuri.org/")]  [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  [System.Web.Script.Services.ScriptService]  public class PetService : System.Web.Services.WebService {  public PetService () {//scommentare la linea se si usano componenti designed     //InitializeComponent(); }  [WebMethod]public List<string> GetPetInfo()  {    List<string> petInfo = new List<string>();  PetClassesDataContext petsDB = new PetClassesDataContext();    var pets = from pet in petsDB.Pets select pet;    foreach (var pet in pets)  {petInfo.Add("My pet is named " + pet.Name + ". It is a " +     (pet.Gender == true ? "male" : "female") + " " + pet.Breed + " that weighs " + pet.Weight + " pounds. " + pet.Notes + " ");    }    return petInfo;}  }

 

<a href="/img/11/iframe_accData4.html" title="Vedi esempio">Vedi esempio</a>;

 

Il nuovo codice ora utilizza la classe DataContext creata daltemplate LINQ to SQL Class ed espone il database al nostrocodice. In questo modo gli sviluppatori non dovrannopiù saper padroneggiare SQL e linguaggi per databasema possono interrogare e gestire basi di dati nella stessamaniera in cui lo farebbero per una collezione di oggetti. Ilcodice soprastante è inoltre molto compatto. Laseconda riga di codice è una query che lega una querySQL "Select * From Pets" dove ognielemento recuperato corrisponde ad una riga nel database.

Non solo il Web service che risiede sul server puòbeneficiare dall'utilizzo di LINQ, anche le applicazioniSilverlight possono tratte i loro vantaggi. Il gestore deglieventi che richiama il metodo web viene mostrato qui sottodopo esser stato convertito a LINQ.

Es 2.2: Page.xaml.cs

using System;  using System.Linq;  using System.Collections.Generic;  using System.Windows;  using System.Windows.Controls;  using System.Windows.Documents;  using System.Windows.Ink;  using System.Windows.Input;  using System.Windows.Media;  using System.Windows.Media.Animation;  using System.Windows.Shapes;    namespace PISCLINQ  {    public partial class Page : Canvas    {public void Page_Loaded(object o, EventArgs e)  {  // Richiesto per inizializzare le variabili  InitializeComponent();}public void GetPetInfo(object o, MouseEventArgs e)  {    PISCLINQ.localhost.PetService svc = new PISCLINQ.localhost.PetService();  IEnumerable<string> pets = from petInfo in svc.GetPetInfo()  select petInfo;    // mostra i risultati  foreach (string pet in pets) {tbOutput.Text += pet;  }}    }  }

 

<a href="/img/11/iframe_accData5.html" title="Vedi esempio">Vedi esempio</a>;