mercoledì 30 luglio 2008

Inizia a diventare sempre più interessante.
Via via javascript viene messo da parte (per quello che vede lo sviluppatore finale) e vengono creati dei controlli ad hoc.

Potete leggere tutte le info quì: http://blogs.msdn.com/publicsector/default.aspx

lunedì 21 luglio 2008

Ultimamente ho riaffrontato un problema che avevo già affrontato con Davide:

Inserire dei controlli a runtime in un updatepanel.

Per farvi capire il problema, provate ad eseguire il seguente codice, ogni qual volta dovete aggiornare il vostro update panel:

                TextBox newtxt = new TextBox();                             
                newtxt.ID = Guid.NewGuid().ToString();                      
                Literal l = new Literal();                                  
                l.Text = "<br />";                                          
                UpdatePanel1.ContentTemplateContainer.Controls.Add(newtxt); 
                UpdatePanel1.ContentTemplateContainer.Controls.Add(l);      

vedrete che verrà inserito un nuovo controllo TextBox all'interno dell'updatepanel.
Se proverete a rilanciare il codice, verrà creata una nuova TextBox e perderete quella vecchia.

Questo capita perchè dopo il postback i controlli inseriti a runtime non vengono ricreati. Toccherà a noi occuparci della ricreazione degli elementi utilizzando la ViewState della pagina:

Default.aspx

<body>                                                                              
    <form id="form1" runat="server">                                                
    <asp:ScriptManager ID="ScriptManager1" runat="server">                          
    </asp:ScriptManager>                                                            
    <div style="float: left">                                                       
        <asp:Label ID="lblOutUpdate" runat="server" /><br />                        
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">                          
            <ContentTemplate>                                                       
                <asp:Label ID="lblInUpdate" runat="server" /><br />                 
                <asp:TextBox ID="txtUpdatePanel0" runat="server" /><br />           
            </ContentTemplate>                                                      
            <Triggers>                                                              
                <asp:AsyncPostBackTrigger ControlID="bntOk" EventName="Click" />    
            </Triggers>                                                             
        </asp:UpdatePanel>                                                          
    </div>                                                                          
    <div style="float: right">                                                      
        <asp:Button ID="bntOk" runat="server" Text="Ok" onclick="bntOk_Click" />    
    </div>                                                                          
    </form>                                                                         
</body>                                                                             
Default.aspx.cs
    public partial class _Default : System.Web.UI.Page                                  
    {                                                                                   
        protected void Page_Load(object sender, EventArgs e)                            
        {                                                                               
            lblOutUpdate.Text = "Out updatepanel: " + DateTime.Now.ToString();          
        }                                                                               
                                                                                        
        protected void bntOk_Click(object sender, EventArgs e)                          
        {                                                                               
            lblInUpdate.Text = "In updatepanel: " + DateTime.Now.ToString();            
            txtUpdatePanel0.Enabled = false;                                            
                                                                                        
            var r = from q in Request.Form.AllKeys                                      
                    where q.StartsWith("txtUpdatePanel") && !q.Equals("txtUpdatePanel0")
                    select q;                                                           
                                                                                        
            for (int i = 0; i < r.Count(); i++)                                         
            {                                                                           
                TextBox newtxt = new TextBox();                                         
                newtxt.ID = r.ElementAt(i);                                             
                newtxt.Text = Request.Form.Get(r.ElementAt(i));                         
                newtxt.Enabled = false;                                                 
                Literal l = new Literal();                                              
                l.Text = "<br />";                                                      
                UpdatePanel1.ContentTemplateContainer.Controls.Add(newtxt);             
                UpdatePanel1.ContentTemplateContainer.Controls.Add(l);                  
            }                                                                           
                                                                                        
            TextBox txt = new TextBox();                                                
            txt.Text = "";                                                              
            txt.ID = "txtUpdatePanel" + (r.Count() + 1).ToString();                     
            UpdatePanel1.ContentTemplateContainer.Controls.Add(txt);                    
        }                                                                               
    }                                                                                   

In pratica, ogni qual volta si scatenerà l'evento associato all'update panel, andremo a recuperare tutti i controlli creati dinamicamente, li ricreeremo con i valori inseriti ed inseriremo il nuovo controlo che potrà esser utilizzato dall'utente.

Spero possa tornarvi utile.

Tags:

domenica 13 luglio 2008

Giocando un pò con i prodotti live, sopratutto con Virtual Earth, ho trovato ques'utile tool:

http://www.codeplex.com/VEJS

Tags:

martedì 1 luglio 2008

Google si sta muovendo per la produzione del suo Sharepoint?
Link

Tags:

lunedì 30 giugno 2008

Martin Fowler: "a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior"

Chi tra voi non ha mai lavorato su un vecchio codice, di un vecchio progetto?!?!

Beh beati voi... a me, purtroppo, è capitato spesso.

In questo contesto il refactoring si fa strada, per rimuovere duplicati di codice, semplificarne la complessità logica e per chiarire il codice esistente.

Possiamo fare del refactoring su grossi pezzi di codice o solamente sul nome di una variabile, importante è che il tutto migliori la comprensione del codice.

Ricordiamoci che è buona norma effettuare refactoring a piccoli passi anche di grossi pezzi di codice e di farsi aiutare dai test, affinchè possiamo capire subito se stiamo introducendo degli errori.

Le motivazioni tipiche che spingono al refactoring:

  • Semplificare la scrittura di nuovo codice
  • Migliorare il design del codice esistente
  • Migliorare la capacità d'espressione del codice affinchè chi lo legge riesce a capirlo. E' inutile inserire dei commenti nel codice
  • Rendere meno noioso lavorare sul progetto

Refactoring to patterns
Refactoring to patterns è il processo che unisce il refactoring del codice ai patterns.

Ciò non significa che ogni qual volta vediamo un pezzo di codice da sistemare dobbiamo per forza applicare un pattern.

giovedì 19 giugno 2008

Non so quanti di voi l'hanno già fatto, ma vi consiglio di vedere i video su:

ASP.NET Dynamic Data

Tags:

venerdì 13 giugno 2008

Proprio l'altro giorno, mentre facevo la demo per LINQ, mi domandavo perchè ancora si usasse Northwind come database per fare le demo.

Oggi ritrovo questo bellissimo post.

Tags:

sabato 7 giugno 2008

Guardando un pò di video in rete ho potuto scoprire una funzionalità di LINQ che non conoscevo per nulla.

LINQ offre la possibilità di creare file XML "al volo" specificando la sorgente dei dati.
Tutto questo è fattibile grazie alle seguenti nuove classi:

system.xml.linq

I seguenti esempi si basano sul database di esempio AdventureWorksDB.msi installato SQL Express.

Creazione di un file XML da una sorgente dati.

Una volta creato il DataContext tramite il file dbml (chiamato per l'occasione AdventureWorks), ho importato la vista vEmployee:

vEmployees 

Fatto questo si procede con il seguente codice:

            AdventureWorksDataContext db = new AdventureWorksDataContext();
                                                                           
            db.Log = Console.Out;                                          
                                                                           
            XElement xel = new XElement("Result",                          
                from c in db.vEmployees                                    
                where c.City == "Seattle"                                  
                where c.FirstName.Length >= 5                              
                select new XElement("Employee",                            
                    new XAttribute("EmployeeID", c.EmployeeID),            
                    new XElement("FirstName", c.FirstName),                
                    new XElement("JobTitle", c.JobTitle)                   
                    ));                                                    
                                                                           
            FileStream fs = File.OpenWrite("Result.xml");                  
            StreamWriter sw = new StreamWriter(fs);                        
            sw.Write(xel.ToString());                                      
            sw.Close();                                                    
            fs.Close();                                                    

Il codice di sopra genererà i file xml Result.xml che conterrà un set di dati:

result.xml 

Per un'esaustiva spiegazione della classe XElement, fate riferimento alle MSDN.

Join fra dati ottenuti da file xml.

Importo nel mio DataContext altre due tabelle presenti nel database AdventureWorks:

  • SalesPerson
  • Contact
  • Employee

LINQ, quando vengono importate delle tabelle, si occuperà della gestione delle relazioni.
Quindi, una volta portate le due tabelle nel vostro file dbml, vedrete graficamente la relazione tra la tabella SalesPerson, la tabella Contact e la tabella Employee:

relationship

Le relazione sono basaste, per Employee con il campo EmployeeID con il campo SalesPersonID della tabella SalesPerson.
E la tabella Employee con la tabella Contact tramite il campo ContactID.

Genero tre file xml che conterranno i dati presenti nelle tabelle e che ci serviranno per la dimostrazione:

  • SalesPersons.xml
            AdventureWorksDataContext db = new AdventureWorksDataContext();
            XElement xel = new XElement("SalesPersons",                    
                from c in db.SalesPersons                                  
                select new XElement("SalesPerson",                         
                    new XElement("SalesPersonID", c.SalesPersonID),        
                    new XElement("SalesLastYear", c.SalesLastYear)));      
            FileStream fs = File.OpenWrite("SalesPersons.xml");            
            StreamWriter sw = new StreamWriter(fs);                        
            sw.Write(xel.ToString());                                      
            sw.Close();                                                    
            fs.Close();                                                    
  • Contacts.xml
            AdventureWorksDataContext db = new AdventureWorksDataContext();
            XElement xel = new XElement("Contacts",                        
                from c in db.Contacts                                      
                select new XElement("Contact",                             
                    new XAttribute("ContactID", c.ContactID),              
                    new XElement("FirstName", c.FirstName),                
                    new XElement("LastName", c.LastName),                  
                    new XElement("EmailAddress", c.EmailAddress)));        
            FileStream fs = File.OpenWrite("Contacts.xml");                
            StreamWriter sw = new StreamWriter(fs);                        
            sw.Write(xel.ToString());                                      
            sw.Close();                                                    
            fs.Close();                                                    
  • Employees.xml
            AdventureWorksDataContext db = new AdventureWorksDataContext();
            XElement xel = new XElement("Employees",                       
                from c in db.Employees                                     
                select new XElement("Employee",                            
                    new XAttribute("EmployeeID", c.EmployeeID),            
                    new XElement("LoginID", c.LoginID),                    
                    new XElement("Title", c.Title)));                      
            FileStream fs = File.OpenWrite("Employees.xml");               
            StreamWriter sw = new StreamWriter(fs);                        
            sw.Write(xel.ToString());                                      
            sw.Close();                                                    
            fs.Close();                                                    

Adesso, ipotizziamo che questi tre files non sono stati creati da noi ma sono stati mandati da un nostro cliente tramite dei vecchi applicativi, questo ci chiede di creare un nuovo file xml dove, in base al SalesPersonID del primo file, può ritrovare dati presenti nel file Contacts.xml e Employess.xml, ecco come LINQ ci verrà in aiuto:

            XElement employees = XElement.Load("Employees.xml");                        
            XElement contacts = XElement.Load("Contacts.xml");                          
            XElement salesPersons = XElement.Load("SalesPersons.xml");                  
                                                                                        
            XElement xel = new XElement("NewContacts",                                  
                from s in salesPersons.Elements("SalesPerson")                          
                join e in employees.Elements("Employee")                                
                on (int)s.Element("SalesPersonID") equals (int)e.Attribute("EmployeeID")
                join c in contacts.Elements("Contact")                                  
                on (int)e.Attribute("EmployeeID") equals (int)c.Attribute("ContactID")  
                select new XElement("NewContact",                                       
                    e.Attribute("EmployeeID"),                                          
                    c.Element("FirstName"),                                             
                    c.Element("LastName"),                                              
                    c.Element("EmailAddress"),                                          
e.Element("Title"), s.Element("SalesLastYear"))); FileStream fs = File.OpenWrite("NewContacs.xml"); StreamWriter sw = new StreamWriter(fs); sw.Write(xel.ToString()); sw.Close(); fs.Close();

in pratica, come prima utiliziamo gli XElement come sorgenti dati e facciamo le join che ci servono per poter ottenere i dati dai vari file xml.

Il risultato ottenuto sarà:

 newcontacts.xml

Strabiliante :D

Per qualsiasi dubbio vi consiglio di far riferimento a questo video:

http://www.microsoft.com/emea/msdn/spotlight/sessionh.aspx?videoid=317

Buon divertimento!!!

Tags:
 

Quando si dice "il buon giorno si vede dal mattino", ecco questa mattina il buon giorno.

E' stata rilasciata la Beta2 di Silverlight.

Per maggiori approfondimenti:

http://weblogs.asp.net/scottgu/archive/2008/06/06/silverlight-2-beta2-released.aspx

lunedì 26 maggio 2008

Motivazione al refactoring:
Sviluppare una classe con più costruttori creerà qualche disagio allo sviluppatore che dovrà decidere a quale costruttore affidarsi per istanziarla; questo comportà un certo tempo di studioe dei parametri dei costruttori e/o magari del codice stesso dei costruttori.

Più costruttori abbiamo nella nostra classe più sarà complicato capirne il comportamento.

Per di più, spesso, molti dei costruttori che creeremo non verranno mai utilizzati appunto per via della complessità nel doverne studiare il comportamento.

Soluzione:
Il Creation Method può aiutare a rendere il tutto più semplice.
Il Creation Method è un metodo statico o non statico utilizzato per creare una nuova istanza.

E' bene chiamare il metodo in maniera chiara, in modo che si capisca immediatamente cosa crea (creaConnessioneFtp(), creaConnessioneHttp() ... etc).

 

Pro e Contro

(+) Comunica meglio il tipo di istanza che creerà

(+) Supera i limiti dei costruttori. Es. non possiamo avere due costruttori con lo stesso numero di parametri

(+) E’ più facile trovare codice non usato

(-) Crea un metodo non standard di creazione di un’istanza

Come fare il refactoring:

  1. Trovare un punto dove la classe viene istanziata.
    A questo punto bisogna estrarne il codice e creare un metodo publico e statico.
    Questo sarà il nostro creation method.

    (compilare e testare)

  2. Trovare tutti i costruttori che istanziano la classe usando il costruttore di prima, cancellare l'istanza ed usare il nuovo creation method.  

    (compilare e testare)

  3. Se il costruttore scelto per il refactoring è chiamato da un'altro costruttore, modificare il costruttore inserendo il creation method

    (compilare e testare)

  4. Ripetere i punti da 1 a 3
  5. Se un costruttore non viene utilizzato fuori dalla classe, renderlo non pubblico

    (compilare e testare)

Variante:
Se durante la crazione dei creation methods vi ritrovate a lavorare con molti creation method, tipo 25, potrebbe essere noioso.
In tal caso è meglio creare un factory che ritorni l'istanza appropriata.

 

martedì 13 maggio 2008

Eh un periodo che, ovunque mi giro, mi chiedono di tirar giù almeno 120.000 records da macchine web server basate su un PIV...

Ho risolto il problema ma adesso devo leggere bene questo articolo:

ASP.NET: 10 Tips for Writing High-Performance Web Applications

Spero vi torni utile anche a voi.

Tags:

mercoledì 7 maggio 2008

Stavo facendo il merge di dati. Alcuni presenti in un db ed altri presi da un XML.

Entrambi sono un elenco di Provincie.
Ho bisogno di sapere se quelle presenti nel db sono presenti nell'XML.
Così ho fatto:

                MyDataContext mdc = new MyDataContext();
                var Provincia = from db in mdc.tblProvincies
                                select db.Provincia.Trim().ToUpper();
XDocument xdoc = XDocument.Load(strFilePath); var xProv = from x in xdoc.Descendants("location") where x.Element("Prov") != null select x.Element("Prov").Value.Trim().ToUpper(); var joined = Provincia.Except(xProv);

Il risultato ottenuto è:

Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator

Facendo un paio di ricerche sulle msdn ho risolto in questa maniera:

                MyDataContext mdc = new MyDataContext();
                var Provincia = from db in mdc.tblProvincies
                                select db.Provincia.Trim().ToUpper();
                XDocument xdoc = XDocument.Load(strFilePath);
                var xProv = from x in xdoc.Descendants("location")
                            where x.Element("Prov") != null
                            select x.Element("Prov").Value.Trim().ToUpper();

                IEnumerable<string> xObjProv = (from xp in xProv select xp).OfType<string>();
                IEnumerable<string> objProv = (from prv in Provincia select prv).OfType<string>();

                var joined = objProv.Except(xObjProv);

Note e consigli, sempre ben accetti.

Grazie

Tags:

lunedì 5 maggio 2008

Appena tornato da Londra...

Cavolo se ci vivrei :D

Tags:

martedì 29 aprile 2008

Passerò per stupido ma debuggando di quà e di là mi è capitato di notare che, una volta instanziata la DataContext, avevo tutti i dati del db in memoria.

Mi domandavo ... come mai?

In più aggiungo... come usereste LINQ per creare un bel test dei dati appena inseriti?

Scusatemi sono un coglione... grazie Davide

Seguendo il consiglio di Davide (cazzo io e quando dimentico il profiler) ho attaccato il profiler.

I dati vengono scaricati quando con l'IntelliSense si prova a visualizzarli -_-

Tags:

domenica 27 aprile 2008

Nuovi video sulla sicurezza postati su asp.net (security) (tnx Scott Mitchell).

Ed altri due video da Lamees Ayman:

 

Un'altro link che potrà tornare in aiuto per le applicazione WCF su Vista:

http://blogs.msdn.com/amitlale/archive/2007/01/29/addressaccessdeniedexception-cause-and-solution.aspx

Tags:
 

Se ricevi un errore 404.3 dalla tua neo applicazione wcf leggi il seguente post:

http://blogs.msdn.com/davidwaddleton/archive/2007/11/02/wcf-and-404-3-errors.aspx

Tags: ,
 

Per chi fosse interessato, al seguente link si possono trovare i video delle sezioni del Mix08: http://sessions.visitmix.com/

 

Sono un appassionato delle metodologie xp, e per questo continuo a studiarle e provare ad applicarle un pò per volta.
Una domanda che è nata in questi giorni è stata: 

  • Quali sono le differenze tra SCRUM e XP?

Rileggendo un articolo di Martin Fowler ho trovato la risposta:
http://martinfowler.com/articles/newMethodology.html

Martin dice che le più grandi differenze sono:

  • Scrum concentrates on the management aspects of software development
  • Scrum dividing development into thirty day iterations (called
    'sprints') and applying closer monitoring and control with daily scrum
    meetings
  • Scrum places much less emphasis on engineering practices

Continuo a preferire XP perchè mi piace l'approccio TDD.
Cosa ne pensate?

Tags: , ,
 

A questo indirizzo: http://www.visifire.com/silverlight_charts_gallery.php

Potete trovare vari charts con d'esempio, sviluppati in Siliverlight.

Veramente carini.

 

ASP.NET offre la possibilità di criptare i dati all'interno della ViewState in moda da incrementare la sicurezza.

Per far ciò abbiamo due possibilità:

1 - Tramite il file web.config, abilitiamo il criptaggio della ViewState per tutta l'applicazione:
  <configuration>
      <system.web>
      <pages viewStateEncryptionMode="Always" />

2 -  Solo per una pagina specifica:

<%@ Page Language="C#" Trace="false" ViewStateEncryptionMode="Always" %>
 

Se la tua applicazione non usa le session puoi migliorarne le prestazioni della tua applicazione disabilitando le sessioni.

Le sessioni si possono disabilitare, per tutta la sezione inserendo la seguente opzione nel file di web.config:

    <system.web>
    <sessionState mode="Off" />

Oppure su una singola pagina:

<%@ Page Language="C#" Trace="false" EnableSessionState="False" %>
Tags:

 

venerdì 25 aprile 2008

Leggendo Refactoring to Patterns sono venuto a conoscenza dell'iniziativa che ha avuto l'autore, ormai anni fa (nel 1995), nel creare dei Gruppi di Studio dove vengono analizzati/discussi/utilizzati i vari patterns, tutto orientato al refactoring e al miglioramento del design di un applicativo.

Non sarebbe un'iniziativa carina a cui pensare?

sabato 29 marzo 2008

Non so quanti di voi stanno oggi sperimentando Silverlight 2 tentando di fare una demo per qualche fantomatico applicativo :D

So solamente che una solution con un'applicativo Silverlight e un servizio WCF, attualmente, non è la cosa più stabile al mondo ... o almeno a quest'ora si ha qualche problema :D

Spero di poter pubblicare la demo il prima possibile.

Per chi potesse interessare, Microsoft ha messo a disposizione: Microsoft Silverlight Streaming

mercoledì 12 marzo 2008

Ragazzi perchè non creiamo un gruppo su linkedin? :o

Tags: