Extension Method

Mi sono sempre chiesto come potevo estendere i metodi, per determinati tipi di dati, al fine di facilitarmi una serie di operazioni come una formattazione custom, nel caso di data; effettuare una replace, nel caso di stringhe o addirittura operazioni più complesse.

Dal framework 3.5 è possibile tutto ciò e vediamo come:

Prima di tutto creo una class library impostandola come public static class Extension e aggiungendo per ciascun metodo la seguente sintassi:

public static string ReplaceSQL(this string s)
{
return s.Replace("'", "''");
}

Come si può notare il metodo dovrà essere static e nella parte relativa al passaggio delle variabili dovrà essere specificato l'attributo this per agganciare quanto abbiamo realizzato nell'elenco metodi del tipo di dato indicato (this string).

In questo modo nel momento in cui la classe verrà aggiunta come riferimento e aggiunto il namespace al nostro progetto tutte le variabili il quale tipo è stato esteso troveremo il metodo che abbiamo realizzato, lo si potrà notare con l'intellisense dalla nuova icona introdotta rappresentata dal cubo viola con una freccia blu rivolta verso il basso.

.NET Campus 2010

Roma 13 marzo 2010 presso la Facoltà di Ingegneria Università Roma 3 (via della Vasca Navale, 79):

è un evento per sviluppatori organizzato dal gruppo DevLeap in collaborazione con il gruppo dei Microsoft Student Partner e le Community più attive per fornire a studenti e aziende un’intensa mattinata di sessioni tecniche presso l’università Roma Tre. Insieme alle sessioni tecniche orientate alle novità che ruotano intorno al mondo .NET, la giornata rappresenta un momento unico dove aziende e studenti possono incontrarsi per confrontare i loro mondi e unire le loro esperienze.

L'evento è gratuito per maggiori informazioni visitate i siti:

http://www.dotnetcampus.it/

http://www.aspitalia.it/

Caricare un file XML da remoto tramite XDocument e HttpWebRequest

Nello script precedente abbiamo visto come caricare un file XML remoto. In questo script affrontiamo lo stesso argomento offrendo una soluzione differente basata sul recupero del file tramite la classe HttpWebRequest. A differenze di XDocument, HttpWebRequest permette di personalizzare alcune informazioni relative alla chiamata per il recupero del file da remoto. Un tipico esempio è la personalizzazione del timeout; si può modificare questa proprietà per non far attendere per troppo tempo la nostra applicazione.

private XDocument GetRSS(string uri){ 
  HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URL); 
  req.Method = "GET"; 
  req.Timeout = 3000; 
  StreamReader streamIn =  
    new StreamReader(req.GetResponse().GetResponseStream()); 
  XDocument xdoc = XDocument.Parse(streamIn.ReadToEnd()); 
  streamIn.Close(); 
  return xdoc; 
}

Nell'esempio viene utilizzato l'oggetto StreamReader per leggere Il flusso dati restituito dalla chiamata tramite HttpWebRequest.
Lo stream ottenuto viene quindi letto e passato a XDocument al fine di avere una struttura XML.

Caricare un file XML remoto tramite la classe XDocument

Il metodo Load dell'oggetto XDocument permette, attraverso uno dei suoi overload, di caricare il contenuto di un file XML. Questo overload accetta in input una stringa con il percorso del file. Quello che rende interessante questo overload è che il caricamento del file funziona anche quando questo è situato in un server remoto, accessibile tramite HTTP.

public XDocument GetRSS(string uri){ 
  return XDocument.Load(uri); 
}

L'URL non deve essere obbligatoriamente un file XML (http://www.sito.local/rss.xml) ma anche il link a una pagina che genera codice XML (http://www.sito.local/generatexml.aspx).

Usare LINQ to XML per creare dinamicamente un file XSD con dati presi da un database

A volte può essere necessario creare il contenuto di un file XSD dinamicamente. Poichè un file XSD altro non è che un file XML, possiamo ricorrere a LINQ to XML. In questo script vedremo come inserire degli elementi di tipo "enumeration" all'interno del tag "restriction".

Le enumeration permettono, nella fase di verifica del file XML, di controllare che l'utente abbia inserito solamente una delle opzioni proposte. Spesso si ha la necessità di creare questi elementi partendo da tabelle di sistema (Ragione Sociale, Comuni, etc.). Vediamo ora il file XSD di partenza senza gli elementi enumeration:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="contacts">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" name="contact">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="firstName" type="xs:string" />
              <xs:element name="lastName" type="xs:string" />
              <xs:element ref="personType" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="personType">
    <xs:annotation>
      <xs:documentation>vincolo</xs:documentation>
    </xs:annotation>
    <xs:simpleType>
      <xs:restriction base="xs:string">
        <!--ENUMERATION Tipologie Persone-->
      </xs:restriction>
    </xs:simpleType>
  </xs:element>
</xs:schema>

All'interno del tag restriction è stata commentato l'area in cui si andranno a creare dinamicamente le enumeration. Innanzitutto, carichiamo nella variabile xmlDoc, di tipo  XDocument, il file XSD:

XDocument xmlDoc =  
XDocument.Load( 
  Path.Combine( 
    AppDomain.CurrentDomain.BaseDirectory, "XmlToSchema1.xsd" 
  ) 
);

Per accedere puntualmente agli elementi dello Schema è necessario abbinare il loro nome al namespace indicato all'inizio del file (xmlns:xs=, xs contiene lo schema xml), questo argomento è stato dettagliato nello script #81 (http://www.linqitalia.com/script/81/Esaminare-Documenti-XML-Namespace-Utilizzando-LINQ-XML.aspx):

XNamespace xs = "http://www.w3.org/2001/XMLSchema";

Attraverso LINQ to XML creiamo la query che restituisce il contenitore personType:

var obj = (from s in xmlDoc.Descendants(xs + "element") 
              where s.FirstAttribute.Value == "personType" 
              where s.FirstAttribute.Name.LocalName != "ref" 
              select s).FirstOrDefault();

senza s.FirstAttribute.Name.LocalName != "ref" la query avrebbe restituito anche l'elemento ref che serve per referenziare una sequence nello schema.
A questo punto non rimane che accedere al tag restriction, contenuto in obj, con un'altra query LINQ to XML per effettuare successivamente la creazione degli elementi di enumerazione:

var objrestriction = (from s in obj.Descendants(xs + "restriction") 
                            select s).FirstOrDefault();

Attraverso il metodo Add dell'oggetto objrestriction (visto come XElement) potranno essere creati i nodi nel seguente modo (per semplicità creiamo direttamente i valori):

//Fare il ciclo per tutti gli elementi che si vogliono enumerare... 
objrestriction.Add( 
  new XElement(xs + "enumeration", new XAttribute("value","Persona Fisica"))); 
objrestriction.Add( 
  new XElement(xs + "enumeration", new XAttribute("value","Persona Giuridica")));

dopo queste modifiche salviamo il file ed il risultato sarà il seguente.

<xs:element name="personType">
  <xs:annotation>
    <xs:documentation>vincolo</xs:documentation>
  </xs:annotation>
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:enumeration value="Persona Fisica" />
      <xs:enumeration value="Persona Giuridica" />
    </xs:restriction>
  </xs:simpleType>
</xs:element>

Month List