Redazione
a- a+

Accesso ai dati

Silverlight: accesso ai dati

Serializzazione

In un tipico scenario di comunicazione fra due macchine in Rete, il client e il server si passano rispettivamente dei messaggi di richiesta e di risposta in formato testuale. Tutti gli elementi trasportati in Rete vengono prima convertiti in testo (questo vale anche per i dati multimediali), trasportati al client per poi venir ricreati dal testo per ottenere nuovamente il loro formato originale. Il processo di conversione di un oggetto complesso nella sua rappresentazione testuale viene chiamato serializzazione, mentre il processo inverso viene definito deserializzazione.

I formati più comuni utilizzati per trasportare dati nel Web sono XML XML, SOAP e JSON. Il .NET Framework lato server e quello incluso in Silverlight hanno entrambi la possibilità di serializzare e deserializzare i dati.

Accesso ai dati

Bisogna ricordarsi che tipicamente i dati memorizzati in un database risiedono su un server remoto mente un'applicazione Silverlight risiede sulla macchina lato client. Per recuperare tali dati remoti quindi, la richiesta dev'essere inoltrata al server, proprio come per ogni altra applicazione Web. In quest'articolo discuteremo i vari modi per accedere ai dati in Silverlight.

Memorizzazione isolata

Per via di restrizioni di sicurezza per un'applicazione Silverlight (la famosa "sandbox" in cui opera), un'applicazione Silverlight non può leggere files dalla macchina del client a meno che non siano memorizzati in maniera isolata. Quindi, un'applicazione Silverlight è piuttosto limitata nelle sue capacità per memorizzare i dati localmente, ad ogni modo dei semplici files possono essere creati per memorizzare semplici dati e settaggi.

I file XML possono essere creati con un'applicazione Silverlight, ma devono avere la loro azione settata a Embedded Resource in modo tale che quando l'applicazione viene generata, i file XML vengono compilati in assembly. Questo limita la possibilità di modificare i file e che questi possano contenere dati dinamici condivisi con altri utenti dell'applicazione.

Silverlight include classi per lavorare con XML, ad ogni modo queste classi sono concepite per leggere una stringa XML in entrata (come quella proveniente da una chiamata ad un Web service) e non per leggere file XML.

Accedere ai dati usando SOA

Come descritto in precedenti articoli, un'applicazione Silverlight può effettuare delle chiamate ad un Web service. Tali chiamate possono trasportare dati usando puro XML (POX - Plain Old XML) o JSON. Inoltre un Web service invocato da un'applicazione Silverlight deve risiedere nello stesso dominio dell'applicazione, come precauzione di sicurezza e in quanto tale, limita da un lato le possibilità di Silverlight ma dall'altro non limita cosa può fare un Web service richiamato dalle applicazioni. Un Web service richiamato da Silverlight agisce come un proxy per l'applicazione Silverlight e può chiamare qualsiasi risorsa per conto dell'applicazione e ritornare i risultati. Ad esempio un'applicazione Silverlight può invocare un Web service che risiede sullo stesso dominio dell'applicazione e questo servizio a sua volta potrebbe richiamare un altro Web service fuori dal dominio dell'applicazione oppure potrebbe eseguire delle query ad un database. Questi metodi rappresentano le modalità standard per un'applicazione Silverlight di recuperare le risorse dei server.

Il servizio che un'applicazione Silverlight richiama può assumere la forma di un Web service ASP.NET o un servizio WCF. Come è stato visto in articoli passati, il progetto ASP.NET Futures è stato concepito esattamente per testare il servizio che può essere redirezionato per trasportare dati attraverso JSON. Il seguente metodo Web viene usato per connettersi a un database SQL Server e ritorna risultati in un ArrayList. Un ArrayList può essere ridimensionato dinamicamente ed è serializzabile. Il valore più evidente ritornato da un metodo Web che ritorna risultati da un database è un DataSet ADO.NET. Ad ogni modo i DataSet non sono supportati al 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ò essere aggiunta allo stesso progetto del Web service che verrà invocato. questo ci assicura che sia l'applicazione Silverlight, sia il Web service risiedano nello stesso dominio e siano facilmente testabili all'interno di Visual Studio 2008. La figura seguente mostra un file XAML sviluppato per ottenere delle informazioni dal metodo Web visto all'esempio 1.1 e mostra i risultati in un TextBlock.

Si può aggiungere un riferimento Web all'applicazione Silverlight per riferire il Web service. Una volta completato, la regione Get Pet Information è cliccabile per scatenare il gestore degli eventi che invoca il Web service e mostra i risultati nella TextBlock. Il seguente listato XAML viene usato per generare la pagina vista 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 il Web 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 service dall'applicazione Silverlight è aggiungere il collegamento Silverlight al progetto ASP.NET Futures e poi aggiungere l'elemento asp:Xaml nella pagina di test Default.aspx. Premete F5 e testate l'applicazione. Dovreste ottenere i risultati riportati in figura.

 

Language Integrated Query (LINQ)

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

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

LINQ è n grado di interrogare qualsiasi oggetti che implementi l'interfaccia Enumerable. LINQ presenterà un nuovo paradigma di programmazione ai progammatori .NET esperti ma la nuova funzionalità e i benefici che se ne traggono dovrebbero essere recepiti facilmente dai più.

Come esempio di implementazione LINQ, creeremo lo stesso esempio usato in precedenza ma utilizzando LINQ nel Web service per accedere ai dati memorizzati in SQL Server cosi come per il codice che sta dietro l'applicazione Silverlight per iterare i risultati.

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

Una volta che la classe è stata aggiunta, si possono creare classi di dati spostando le tabelle da Server Explorer all'area di disegno delle classi. La figura sottostante mostra la classe con la tabella Pets che viene aggiunta nell'area disegno.

La versione semplificata del metodo web che utilizza LINQ per recuperare le informazioni da SQL Server 2005 viene mostrata qui 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 dal template LINQ to SQL Class ed espone il database al nostro codice. In questo modo gli sviluppatori non dovranno più saper padroneggiare SQL e linguaggi per database ma possono interrogare e gestire basi di dati nella stessa maniera in cui lo farebbero per una collezione di oggetti. Il codice soprastante è inoltre molto compatto. La seconda riga di codice è una query che lega una query SQL "Select * From Pets" dove ogni elemento recuperato corrisponde ad una riga nel database.

Non solo il Web service che risiede sul server può beneficiare dall'utilizzo di LINQ, anche le applicazioni Silverlight possono tratte i loro vantaggi. Il gestore degli eventi che richiama il metodo web viene mostrato qui sotto dopo 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>;



Ti potrebbe interessare anche

commenta la notizia

C'è 1 commento
Pier Paolo
Condividi le tue opinioni su questo articolo!