Home

 
 
 
 
 



 
 
 
 

 
 
 

 
 
 
 
 









Blog2theMax
Il blog del team di Code Architects

Parte la serie dei seminari Microsoft Innovation Days, organizzati (quasi tutti) in collaborazione con Code Architects.

  • Marco Bellinaso sarà domani 19 febbrario a Torino, e parlerà di Programmare per il web con ASP.NET e le Ajax extensions.
  • Il sottoscritto sarà giovedi 22 febbrario a Padova, con una giornata dedicata alla Migrazione da Visual Basic 6 a Visual Basic.NET 2005.
  • Il 17 aprile sarà la volta di Giuseppe Dimauro, che a Roma illustrerà le potenzialità di Windows Vista for Developers.
  • La serie di seminari si conclude il 18 aprile a Roma, dove Marco Bellinaso mostrerà tecniche e trucchi dello Sviluppo con Microsoft Office System 2007.

Giovedì parlerò quindi a Padova di migrazione da VB6 a VB2005. Certo, è un argomento "vecchio" e molti lettori di questo blog probabilmente si chiederanno "come, ancora VB6?" La realtà è che sono ancora tantissime le aziende che NON sono ancora passate a .NET Framework, e spesso - ad essere onesti - per buoni motivi. La verità è che gli attuali strumenti di migrazione, ovvero l'Upgrade Wizard di Artinsoft (inserito in Visual Studio 2005) fanno un lavoro di qualità abbastanza discutibile (per usare un eufemismo), non perchè siano scritti male ma perchè la distanza tra i due linguaggi è davvero troppo ampia.

Nell'ultimo anno ho lavorato a tempo pieno sui problemi della migrazione di applicazioni VB6 e ho accumulato un bel po' di tecniche interessanti su come affrontare la migrazione, sia preparando adeguatamente il sorgente VB6 sia procedendo alla creazione di una libreria di supporto VB2005 che accorcia questa distanza tra i linguaggi. E ho anche una bella quantità di piccole e grandi "trucchi" per risolvere i tanti problemi che la migrazione crea, inclusi molti problemi che non ho mai trovato documentati in nessun libro o articolo.

2/18/2007 10:15:07 AM (GMT Standard Time, UTC+00:00) #  | Comments [0] | 

Da quando ho pubblicato lo Starter Kit TheBeerHouse -- il sito web sviluppato come esempio per il mio libro "ASP.NET 2.0 Website Programming" -- su CodePlex, il sorgente ha già avuto più di 50.000 download. Niente male direi, anche considerando che se dovessi fare una stima per i download fatti direttamente dal sito di Wrox da molti lettori, e quelli fatti da .Net2TheMax prima che creassi l'account su CodePlex, i download sarebbero almeno 60-65.000.

Il sito implementa un mini CMS, una sezione di e-commerce, newsletter, sondaggi, forum gestione account, feature di personalizzazione e localizzazione, e qualcos'altro. Quindi se sviluppate in ASP.NET 2.0 e non l'avete ancora scaricato, magari lo potreste troverare interessante, anche come punto di partenza per qualche vostro sito content-based.

Questo post però non è solo a scopo pubblicitario, ma anche e soprattutto un tentativo di coinvolgere qualcuno a collaborare e far crescere questo progetto, implementando nuove funzionalità come la ricerca, un modulo per il conteggio e l'analisi di accessi e pagine viste, una vera photo gallery (ora si possono pubblicare foto, ma sotto forma di articoli all'interno del CMS), e magari qualcos'altro. Se avete qualche idea e vi piacerebbe collaborare, contattatemi!

1/7/2007 9:13:16 PM (GMT Standard Time, UTC+00:00) #  | Comments [0] | 

Già, proprio così, qualche giorno fa nientemeno che Scott Guthrie ha pubblicato su Amazon una recensione a 5 stelle del mio libro, dicendo tra le altre cose:

"I am very impressed with this book, and have worked with a number of customers who have also found it extremely useful..."
"The result is a very readable book that provides a great deal of context about how ASP.NET 2.0 works, and how the different features integrate together..."
"I'd definitely recommend this book to anyone who understands the basics of how ASP.NET works already, and is looking for a good book to take them to the next level and really start to build applications with it."
<clicca qui per l'intera recensione>

Non posso credere di aver ricevuto l'onore di tali parole da colui che è universalmente conosciuto come il padre di ASP.NET (e non è solo questo...Scott dirige anche i team di CLR, IIS, Atlas, WinForms, Compact Framework, Commerce Server, WPF, VWD...). Sembra anche che questa sia la prima recensione che Sctott ha scritto su Amazon, il che ai miei occhi fa diventare la cosa ancora più importante :-)

Quindi wow, grazie mille Scott, parole come le tue -- e quelle dei molti altri lettori che mi hanno contattato per esprimere il loro apprezzamento -- sono veramente la più grande soddisfazione dopo aver investito così tanto tempo ed energie a scrivere il libro!

12/22/2006 3:45:38 PM (GMT Standard Time, UTC+00:00) #  | Comments [0] | 

Fate un Web Service che riceve una stringa e restiuisce una stringa.
Fate si che l'implementazione del web service restituisca System.Environment.NewLine (la sequenza /r/n).
Fate quindi un chamante del web service e fate si che il chiamante passi anch'esso System.Environment.NewLine.
Lanciate in debug e vedete cosa succede : da entrambi i lati riceventi la sequenza /r/n viene trasformata in /n .. come mai ?

Il fatto è che c'è una specifica dell'XML che dice che una tale sequenza deve essere trasformata (normalizzata) in /n (specificatamente , la sequenza di caratteri asci 13 , 10 deve essere trasformata in 10.
Il responsabile della sparizione del /r è il lato ricevente: di default i web services usano un xmltextreader con la proprietà Normalization impostata a true (provate a serializzare e quindi deserializzare in maniera esplcita un oggetto avente una proprietà stringa impostata con un /r/n usando l'XMLSerializer a cui passate un xmltextreader con la proprietà Normalization impostato prima a true e poi false).
La sparizione della sequenza /r/n puo' essere un bel problema per molte applicazioni.

Per fortuna esiste una soluzione : Per evitare che venga persa la sequenza nella risposta del Web Service occorre intervenire sul proxy lato client andando in override del metodo GetReaderForMessage nel modo seguente:

protected override System.Xml.XmlReader GetReaderForMessage(
 System.Web.Services.Protocols.SoapClientMessage message, int bufferSize) {
 System.Xml.XmlReader l_tmp = base.GetReaderForMessage(message, bufferSize);
  ((System.Xml.XmlTextReader)l_tmp).Normalization = false;
  return l_tmp;
}

(ovviamente non fatelo sul proxy generato dinamicamente , derivate da quello)
Lato server la cosa è piu' articolata : Create una classe custom che deriva da SoapServerProtocolFactory. Tale classe deve restituire un'altra vostra classe custom che deriva da SoapServerProtocol public class MyWSFactory :

System.Web.Services.Protocols.SoapServerProtocolFactory {
 protected override System.Web.Services.Protocols.ServerProtocol CreateIfRequestCompatible(
   System.Web.HttpRequest request) {
  if (request.PathInfo.Length > 0) {
   return null;
  }
  if (request.HttpMethod != "POST") { // need reflection to create the internal UnsupportedRequestProtocol class
   Type l_t = Type.GetType
    ("System.Web.Services.Protocols.UnsupportedRequestProtocol, System.Web.Services, Version=2.0.0.0, Culture=neutral, 
    PublicKeyToken=b03f5f7f11d50a3a"
, true);
   Object l_tmp = l_t.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic |
    BindingFlags.Instance | BindingFlags.CreateInstance, null, null, new object[] { 0x195 });
   return (System.Web.Services.Protocols.ServerProtocol)l_tmp ;
   // return new UnsupportedRequestProtocol(0x195);
   }
   return new MyWS();
  } 
   

Ed ecco l'implementazione della SoapServerProtocol custom  in cui si puo' ottenere una referenza all'XMLTextReader utilizzato :

public class MyWS : System.Web.Services.Protocols.SoapServerProtocol {
 protected override System.Xml.XmlReader GetReaderForMessage(
  System.Web.Services.Protocols.SoapServerMessage message, int bufferSize) {
  System.Xml.XmlReader l_tmp = base.GetReaderForMessage(message, bufferSize);
  ((System.Xml.XmlTextReader)l_tmp).Normalization = false;
  return l_tmp;
 }
}

Come ultimo passo dovete aggiungere nel web .config l'entrata seguente per dire ad ASP.NET di agganciare il vostro soapServerProtocolFactory ...

<configuration>
                <system.web>
                               <webServices>
                                               <soapServerProtocolFactory type ="WSFactory.MyWSFactory, WSFactory" />

 

Poteva essere + facile .. ma per adesso le cose stanno cosi' :)


12/22/2006 1:33:32 PM (GMT Standard Time, UTC+00:00) #  | Comments [0] | 

In questo periodo sono occupato quasi settimanalmente con lo Starting Innovation Tour, un ciclo di conferenze gratuite organizzate da Microsoft nelle principali città italiane per mostrare a sviluppatori e partner le principali novità di Vista e Office 2007. Dopo Catania, Napoli, Bologna, Bari e Roma, questa settimana tocca a Padova, poi Milano, Firenze e Torino. A mio parere la conferenza è davvero un'ottima occasione per chi non ha ancora visto con i propri occhi (o toccato con mano, con preferite) le nuove major release dei due prodotti principali di MS. Io mi occuperò delle sessioni su Office, ovvero:

  • Sviluppo con Office 2007 Client Side: come sfruttare il nuovo formato XML dei documenti per modificare o creare nuovi documenti senza avere Office installato - da applicazioni desktop o web - nonchè una panoramica sulla creazione di add-in, Action Pane e ribbon custom.
  • Windows SharePoint Services 3.0: nuove funzionalità per le liste e document library (cestino, supporto per versioning esteso, supporto RSS,...), nuovi template (blog e wiki tanto per essere moderni, ma altro ancora), utilizzo masterpage a-là ASP.NET 2.0, webpart, utilizzo workflow built-in o utilizzo del nuovo SharePoint Designer per la definizione dei propri flussi.
  • Office SharePoint Portal 2007: Excel Services (il motore di calcolo di Excel direttamente sul server + rendering via browser + esposizione del motore tramite web service!), Forms Services (praticamente le form InfoPath via browser!) e Business Data Catalog (indicizzazione e visualizzzione di record presi da un qualunque database o fonte di accesso ai dati esterna)

Insomma, mi sembra ci sia un bel po' di roba da vedere :-) Per non parlare delle bellissime e impressionanti demo grafiche fatte con WPF per Vista! Dai, ci vediamo ad una delle prossime tappe allora...

11/20/2006 2:11:10 PM (GMT Standard Time, UTC+00:00) #  | Comments [0] | 

Al ritorno dalle vacanze ho avuto la graditissima sorpresa di scoprire che TheBeerHouse, il sito web che ho sviluppato come esempio per il libro "ASP.NET 2.0 Website Programming / Problem - Design - Solution" è stato ritenuto da Microsoft come degno di essere pubblicato sulla loro pagina ufficiale degli Starter Kit! Il link al download del codice sorgente punta a CodePlex: ho deciso di aprire li un account in modo da poter condividere fix e modifiche non appena correggo il codice in locale e faccio il check in nel loro sistema di source control.

Un'altra notizia che dovrebbe far parecchio piacere a molti lettori è che finalmente è disponibile anche una versione in VB.NET del codice! Il porting non è ufficialmente supportato, perchè eseguito da Darren J Kindberg, un lettore pieno di buona volontà che non potrò mai ringrazia abbastanza per l'impegno e il supporto dimostrato, anche nel forum ufficiale di Wrox. Buon divertimento :-)

8/20/2006 11:14:19 AM (GMT Daylight Time, UTC+01:00) #  | Comments [0] | 

Proprio così, finalmente il mio libro (finito di scrivere ormai quasi 3 mesi fa!) è disponibile su Amazon per spedizione immediata, al bassissimo costo di 25,19$ (20€)...un ottimo prezzo direi, considerando che la versione precedente (un po' più breve e con un sito di esempio certamente meno professionale e completo di questa edizione) aveva un prezzo di copertina di 50$...

Ultimamente ho pubblicato sul mio blog in inglese degli estratti da alcuni capitoli, che vi elenco di seguito:

- An excerpt from Chapter 2: Enter the Master Page Model
- An excerpt from Chapter 3: Caching Data for Better Performance
- A 2nd excerpt from Chapter 3: Transaction Management
- An excerpt from Chapter 4: Setting Up and Using User Profiles
- An excerpt from Chapter 5: Final Touches - Friendly URLs with URL mappings
- An excerpt from Chapter 7: Creating and Sending E-mails
- An excerpt from Chapter 10: Developing Web Parts
- An excerpt from Chapter 11: Using Page Level Resources

A breve pubblicherò anche l'ultimo estratto, riguardante il deployment del sito, e in particolare sulla precompilazione di pagine e codice, tramite gli strumenti built-in del framework e tramite l'add-in Web Deployment Projects.

NOTA1: una cosa che vorrei far notare riguardo questi estratti è che sono stati presi dalla prima parte della sezione Design dei capitoli, ovvero dove introduco le varie novità di ASP.NET 2.0 che servono per lo sviluppo di un certo modulo (membership, gestione articoli, e-commerce, sondaggi, newsletter ecc. ecc.) Ad essere completamente onesto io credo che questa sia la parte un po' più "tipica" e meno "speciale" del libro, perchè molte di queste informazioni si trovano anche in tanti altri libri, e in modo più dettagliato. Come dicevo, infatti, in ciascun capitolo ci sono solo una decina di pagine dedicate all'introduzione dei nuovi controlli e funzionalità...il resto del capitolo è la parte che ritengo decisamente più interessante, essendo dedicata al design e all'implementazione vera e propria, ed è quella che distingue questo libro dai classici reference (che ovviamente non ritengo assolutamente inutili, anzi sono un perfetto e necessario complento a questo libro, da leggere prima, durante e dopo). Le sezioni di Design e Solution però dovrebbero essere lette nella loro completezza per assumere un senso compiuto e riuscire veramente ad insegnare qualcosa, pertanto non avrebbe avuto un gran senso prendere da li degli estratti. Con questo non intendo sminuire il valore di quanto pubblicato, credo che quegli estratti abbiano il loro perchè, soprattutto per chi non conosce ancora le novità di ASP.NET 2.0 e vuole farsene una buona idea leggendo qualcosa di conciso e che va dritto al punto (non essendo per questo superficiale però); solo che non sono realmente rappresentativi del valore che credo il libro abbia.

NOTA2: per il momento Wrox non sembra intenzionata a fare una versione per VB.NET, come invece era stato fatto per la versione precedente. Almeno non inizialmente...ma immagino che potrebbero riconsiderare l'ipotesi se fossero tanti i lettori a richiederla. Quindi, se il libro vi interessa ma C# non è il vostro linguaggio e non siete disposti a leggere nient'altro che VB, fatelo presente a Wrox, o lasciate un commento a questo post.

NOTA3: per il momento non ci sarà un'edizione italiana.

5/12/2006 5:55:23 PM (GMT Daylight Time, UTC+01:00) #  | Comments [0] | 

Se vi interessa vedere (o far vedere ai vostri clienti) cosa i cattivi hacker possono fare con la sql injection insieme al disassembly dei programmi .NET, date una occhiata a questo video: http://www.rockyh.net/AssemblyHijacking/AssemblyHijacking.html. E dopo esservi un po' spaventati (e aver fatto spaventare i vostri clienti) ricordatevi sempre non solo di usare oggetti Command parametrici (che riducono praticamente a zero i rischi di injection), di ridurre i privilegi sotto cui gira l'applicazione asp.net, ma anche di marcare sempre con strong name tutti i vostri assembly, incluso quelli che - apparentemente - gireranno solo e soltanto sulla vostra macchina.

5/11/2006 8:49:25 AM (GMT Daylight Time, UTC+01:00) #  | Comments [0] | 

Per il progetto sul quale stò lavorando c'era la necessità di produrre un PDF sulla base di un report HTML abbastanza complesso, con griglie, immagini, CSS interni all'HTML stesso o in file esterni linkati. Abbiamo provato per giorni ad usare un certo prodotto commerciale piuttosto famoso che fa tutto ciò, ma richiedendo di creare account Windows particolari, configurare in modo appropriato addirittura i browser che stà sul server, creare varie cartelle, configurare l'apertura di porte particolari ecc. ecc. Insomma, bisogna dedicare un server a questo tool, e anche così bisogna perdere del tempo per sistemare il tutto. Stanchi di queste difficoltà per il test e il deployment, ieri mi sono messo a cercare un'alternativa. Risultato :ABCpdf! Questo componente fa davvero tutto quello che ci serve, in modo ottimale a quanto sembra per ora, e la sua installazione e utilizzo sono di una semplicità disarmante: basti dire che in poco più di un'ora ho scaricato e installato il prodotto, mi sono visto un paio di loro esempi, ho riscritto il servizio di generazione di PDF e ho testato che funzionava bene...
Insomma, forse l'altro componente sarà anche in grado di svolgere compiti più complessi (fa da vero e proprio server PDF, mettendo in coda le richieste e smaltendole in modo asincrono), ma se non avete necessità di gestire carichi davvero enormi, e non avete un server da dedicarci, ABCpdf è molto veloce e può fare al caso vostro. Tra l'altro, il componente è gratuito se mettete sul sito un link al produttore (altrimenti c'è una licenza di prova di 30 giorni oltre i quali si dovrà comprare la licenza commerciale)!

Colgo l'occasione di questo post per segnalare anche che nel blog in inglese ho appena pubblicato un nuovo estratto dal mio libro, che mette a confronto le varie tecnologie MS per gestire le transazioni distribuite e non all'interno di applicazioni .NET: transazioni ADO.NET, COM+/SWC e System.Transactions. Il tutto in modo piuttosto conciso (del resto è solo una delle tante cose che introduco nel capitolo 3, riguardanti i fondamenti della progettazione del sito), non è certamente intesa come una trattazione esausitva ma credo possa dare velocemente un'idea delle varie possibilità a chi ancora non ci ha avuto a che fare.

4/7/2006 11:22:52 AM (GMT Daylight Time, UTC+01:00) #  | Comments [2] | 

Negli ultimi tempi sono stato così occupato che il blog purtroppo è dovuto rimanere in fondo alla lista :-(.
Oggi però ho trovato un paio d'ore per aggiornare sul sito americano la pagina del mio libro, e lo dovevo segnalare! Ci trovate una descrizione dettagliata capitolo per capitolo, la mia introduzione, e le foreword di Francesco Balena! Ma soprattutto potete scaricare l'intero sorgente ASP.NET 2.0 / C# del sito TheBeerHouse, usato come progetto di esempio per tutto il libro! Sul sito della Wrox ancora non c'è, ma sono stati così gentili da permettermi di pubblicarlo prima di loro :-) Lo potete quindi scaricare, installare in locale, studiare, modificare ecc. ecc. Tutto gratis ovviamente, in perfetto stile Wrox.

Inoltre, nel blog inglese ho cominciato a pubblicare degli estratti presi dalla sezione Design di alcuni capitoli. Per ora ho pubblicato un post sulle master page, e un altro sul nuovo caching con dipendenze SQL (sia per SQL Server 2000 che 2005, con le dovute differenze). Nei prossimi tempi pubblicherò altri estratti riguardanti la gestione delle transazioni (con ADO.NET, con COM+ o SWC, o con il nuovo namespace System.Transactions), i profili, url remapping, invio di e-mail, webpart e altro ancora.

3/29/2006 6:16:47 PM (GMT Daylight Time, UTC+01:00) #  | Comments [0] | 

Vi anticipo le slide per il webcast architetturale di domani alle ore 11.00 per la durata minima di un'ora e trenta minuti circa

Di cosa parlero' durante il webcast di domani:
- Applicazioni distribuite
- Architetetture basate su servizi
- Componenti utilizzate per applicazioni e servizi
- Criteri di progettazione per le componenti
Cosa non vedremo domani rimandando a degli articoli che preparero' e pubblichero' nei prossimi giorni sul nostro sito http://www.dotnet2themax.it:
- Sicurezza, comunicazione, policy di tipo operazionali di gestione
- Architetture di deployment

A domani, vi aspetto  :)
Giuseppe

DesigningApplicationsAndServicesPublicSlides.ppt (2.28 MB)
2/13/2006 11:31:01 AM (GMT Standard Time, UTC+00:00) #  | Comments [0] | 

Ciao a tutti, 
   vi riporto di seguito il calendario ufficiale dei prossimi webcast architetturali tenuti da Maurizio, Pierre, me ed altri. Il primo appuntamento e' domani. Illustrero' le novita' della rinnovata versione dell'Enterprise Library di Patterns & Practices per poi proseguire fino a giugno con una nutrita serie di argomenti e approfondimenti su tecnologie reali.

Calendario dei prossimi Architect Webcast  
§Febbraio
7/2: Pattern architetturali per la realizzazione di applicazioni e servizi - Parte I
14/2: Pattern architetturali per la realizzazione di applicazioni e servizi - Parte II
21/2: Introduzione alla metodologia agile MSF 4.0 con Visual Studio 2005 Team System
28/2: Progettare il Web Testing nel mondo Enterprise con Visual Studio 2005 Team Test
§Marzo
07/3: BizTalk Server 2006: uno strumento per tutta l'azienda
14/3: BizTalk Server 2006: mille e uno usi di uno strumento versatile
21/3: BizTalk Server 2006 e lo sviluppo di applicazioni orientate ai servizi
28/3: WinFX: Windows Workflow Foundation - Parte I
§Aprile
04/4: WinFX: Windows Workflow Foundation - Parte II
11/4: Realizzare servizi distribuiti con Windows Communication Foundation - Parte I
19/4: Realizzare servizi distribuiti con Windows Communication Foundation - Parte II
27/4: Architettura SOA. Perché non se ne può fare a meno?
§Maggio
09/5: Le applicazioni client negli scenari d'integrazione - Parte I
16/5: Le applicazioni client negli scenari d'integrazione - Parte II
23/5: Interoperabilità e migrazione tra .NET e COM
§Giugno
06/6: Smart Client. Unire il meglio di idee e tecnologie diverse
13/6: Il dato al centro dell'informazione aziendale. Come gestirlo
20/6: Snellire i processi aziendali gestendo il flusso di informazioni con Office
27/6: Smart Document: la nuova faccia del documento

2/6/2006 5:54:25 PM (GMT Standard Time, UTC+00:00) #  | Comments [0] | 

Windows Communication Foundation (WCF) e Windows WorkflowFoundation possono essere utilizzati in un ambiente di produzione.

Ulteriori dettagli qui:

http://msdn.microsoft.com/winfx/getthebeta/golive/default.aspx

BIT e informazioni qui:

http://www.windowsworkflow.net

http://windowscommunication.net

 

 

1/18/2006 7:03:33 PM (GMT Standard Time, UTC+00:00) #  | Comments [0] | 

Ho appena pubblicato qui la versione aggiornata e feature-complete di TheBeerHouse, il sito di esempio per il libro ASP.NET Website Programming di cui ho parlato nell'ultimo post. L'ultima parte è stata implementare il modulo di commercio elettronico. Anche qui non ho voluto fare un esempio sempliciotto, ma ho inserito il supporto per categorie, stati dell'ordine, metodi di spedizione e valute multiple, vari attributi per i prodotti (percentuale di sconto, descrizioni formattate in HTML, immagine piccola e grande, elementi in magazzino ecc.), rating da parte dell'utente, shopping cart persistente anche per utenti anonimi (il login è richiesto solo in fase di completamento dell'ordine), storico ordini personali per controllarne lo stato, pagamento real-time con PayPal, ricerca e amministrazione completa degli ordini da parte di specifici utenti, gestione della disponibilità dei prodotti, e altro ancora.

L'implementazione di questo modulo ha richiesto 4 giorni di lavoro full-time (non proprio 8 ore al giorno...), che ritengo essere abbastanza pochi...soprattutto considerando che comunque non sono stati utilizzati DataSet/DataAdapter e tutti gli aiuti del designer di VS, ma è anche stato sviluppato un completo wrapping dei dati tramite classi DAL e BLL. Dove ASP.NET 2.0 veramente ha aiutato è stato nella gestione della UI però (oltre che nei servizi tipo Membership e Profile, che erano già stati configurati a dovere in precedenza, e che quindi qui non considero): sviluppare tutte le pagine dell'amministrazione, del catalogo e dello shpping cart avrebbero richiesto più di 2 giorni in ASP.NET, senza l'aiuto di controlli come GridView/DetailsView e l'ObjectDataSource di accompagnamento, che riducono drasticamente il codice C# nelle classi di code-beside. Non riesco neanche a pensare poi al confronto con ASP / PHP (che pure molti usando ancora per applicazioni nuove cominciate da zero).

Tirando qualche somma, il progetto completo è composto da 14 tabelle di DB (oltre a quelle usate da ASP.NET ovviamente), 98 stored procedure che incapsulano il 99% del codice SQL necessario, circa 130 classi C# per un totale di circa 15.000 righe, 50 pagine .aspx (di cui 20 di back-end, per amministrare praticamente tutto), 13 user control, 1 master page e 2 temi interscambiabili anche a runtime. Dal momento che ho dovuto lavorare parecchio in fretta è probabile che in giro siano rimasti dei bug...ed è per questo che rinnovo l'invito a provare il sito online, in attesa di poter scaricare tutto il codice e di provarlo in locale. Ora passerò i prossimi 4 gionri a scrivere il capitolo...ormai stò cominciando a pensare che potrei riuscire a sopravvivere :-)

Dato che mi è stato chiesto privatamente da più di qualcuno, dico anche qui che il libro in inglese dovrebbe essere disponibile a febbraio o giù di li. Per la versione italiana non so ancora se e quando...

1/15/2006 10:08:07 PM (GMT Standard Time, UTC+00:00) #  | Comments [0] | 

Dopo la tragica rivelazione di Francesco riguardo i suoi prossimi progetti professionali-editoriali :-) scrivo anch'io un aggiornamento su quello che ho fatto negli ultimi 6 mesi, ovvero lavorare sulla nuova edizione del libro "ASP.NET Website Programming - Problem Design Solution" di Wrox Press (tradotto anche in italiano da HOEPLI nella scorsa edizione). Il libro è stato riscritto completamente da zero, il progetto di esempio è nuovo di pacca, ed è stato sviluppato sfruttando al meglio tutte le nuove caratteristiche di ASP.NET 2.0. Questa volta sono anche l'unico autore, il che spero sarà un bel guadagno per quanto riguarda l'uniformità di stile di scrittura e di sviluppo del codice, nonchè di coerenza e coesione delle varie parti del progetto proposto.

Per chi non conoscesse il libro precedente, lo descrivo proprio in due parole: tratta la progettazione e l'effettivo sviluppo di un intero sito web, utilizzando le ultime tecnologie Microsoft quali appunto ASP.NET 2.0 e SQL Server 2005. Il sito fittizio proposto è quello di un pub, con contenuti dinamici (articoli, gallerie fotografiche ecc.), forum, sondaggi, newsletter, e-commerce, localizzazione delle pagine, membership, profilazione, personalizzazione, e altro ancora. Benchè inizialmente il sito doveva essere solo un esempio piuttosto semplice, al livello dei vari Starter Kit rilasciati da MS, ci ho preso subito gusto e ho implementato nei vari moduli funzionalità piuttosto avanzate che a volte si trovano solo in moduli commerciali. Il tutto perfettamente integrato in un unico sito, pronto per essere messo online, dopo magari una personalizzazione grafica (c'è il supporto per master page e temi multipli, quindi anche questo sarà semplice per chi userà il sito come base per i propri progetti).

Nel mio blog in inglese ho appena pubblicato una breve lista dei capitoli del libro, descrivendo cosa è stato sviluppato (o perlomeno le cose principali, perchè i dettagli sarebbero veramente molti). Ho anche pubblicato online la versione attuale del sito, che ha già tutto ad esclusione della parte di e-commerce. Vi invito pertanto a farci un giretto per capire meglio di che si tratta, magari loggandovi come SampleEditor (maggiori dettagli nella homepage) per poter accedere anche a gran parte della parte amministrativa. NOTA: se vi loggate come SampleEditor le modifiche non saranno salvate, inclusi i post nei forum, i voti per i sondaggi ecc. ecc. Per quello dovreste quindi creare un normale account utente tramite il wizard di registrazione. Resto in attesa di suggerimenti ed eventuali segnalazioni di problemi (possibili, dato che più work-in-progress di così si muore :-))

1/10/2006 3:55:19 PM (GMT Standard Time, UTC+00:00) #  | Comments [0] | 

Durante gli ultimi due giorni ho speso un sacco di tempo sperimentando quanto più possibile le diverse modalità di deployment di ASP.NET 2.0 / VS2005. Mi serviva per fare effettivamente il deployment di un sito che stò sviluppando come esempio per il mio nuovo libro su ASP.NET 2.0, di cui tornerò a parlare tra qualche giorno. Ho usato il tool aspnet_compiler.exe per precompilare il sito, in modo che il caricamento fosse veloce fin dalla prima richiesta dell'utente (a differenza di quanto avviene con ASP.NET 1.x) e anche per proteggere (almeno un minimo) il mio codice da occhi indiscreti. Per chi ancora non lo sapesse, la cosa bella è che si può compilare non solo il codice C#/VB.NET delle classi di code-beside, ma anche tutto il codice di markup che stà all'interno dei file .aspx, .ascx ecc. La cosa "brutta" di aspnet_compiler invece è che crea un sacco di assembly, o uno per ogni pagina, o uno per ogni folder, o comunque gruppi di assembly che possono raggruppare più classi secondo una qualche sua logica. Se la cosa non vi piace si può usare il secondo tool, aspnet_merge, per fondere assieme tutti gli assembly ed ottenerne uno solo, in modo simile a quanto avviene con VS.NET2003, includendo però anche il markup (opzionalmente comunque, non è obbligatorio). Le guide che mi sono state maggiormente utili per studiare i vari switch dei tool, e varie implicazioni derivanti dal loro utilizzo, sono stati i due documenti Word che è possibile scaricare da questa pagina. Dalla pagina è anche possibile scaricare un addin per VS2005, Visual Studio 2005 Web Deployment Projects, che aggiunge all'IDE un nuovo tipo di progetto deployment che permette di compilare e "mergiare" assieme il tutto in modo semplicissimo, senza dover eseguire a mano aspnet_compiler e aspnet_merge. Spuntando un paio di checkbox è possibile compilare tutto in un unico assembly, mica male!

Mentre usavo questi tool e il relativo addin mi sono scontrato con un problema un po' subdolo, che ho pensato di riportare qui nella speranza che vi risparmi un po' di tempo di ricerca e test vari, nel caso vi si dovesse presentare. Quando da VS2005 si creano nuove pagine web, la classe di code-beside non viene inserita all'interno di un namespace esplicito, come faceva VS.NET2003 con il namespace di default, e in fase di compilazione verrà usato sempre ASP. A questo punto vi potreste chiedere: che succede se io ho più pagine default.aspx, con dietro una classe _default? Questa è esattamente la mia situazione, dal momento che ho una default.aspx nella root del sito, un'altra sotto /admin, e altre ancora. Fintanto che si testa il sito sfruttando la compilazione standard non c'è nessun problema, perchè ciascuna pagina viene compilata nel suo assembly e quindi non ci sono errori causati da un tipo con nome duplicato. Bene, ma che succede se poi cerco di usare aspnet_compiler + aspnet_merge per eseguire la precompilazione e fondere tutti gli assembly generati all'interno di uno unico? Indovinate un po'...non funziona, solleva errore dicendo proprio che trova dei tipi duplicati, ovvero più ASP._default corrispondenti alle pagine default.aspx multiple. Capito il problema, la soluzione è stata molto semplice: basta wrappare manualmente ciascuna classe all'interno di un namespace esplicito (sia nel file .cs/.vb che nel file .aspx che referenzia la classe tramite l'attributo inherits), avendo cura di usare namespace diversi per folder diversi, cosicchè il nome intero delle classi di due pagine default.aspx in locazioni diversi siano qualcosa del tipo SampleSite._Default e SampleSite.Admin._Default.

La conclusione è la seguente: definite sempre un namespace esplicito per le vostre pagine e controlli web, anche se è noioso farlo a mano! Diciamo che questa è da sempre una buona regola...solo che a quanto pare VS2005 non la spinge molto...

A proposito, nei prossimi giorni scriverò un altro post descrivendo il libro e il suo sito di esempio (anche se credo che chiamarlo semplicemente "esempio" sia un po' riduttivo :-) )...e pubblicherò il link per esplorarlo direttamente online, compresa la sua sezione amministrativa...in attesa dei sorgenti definitivi ovviamente :-)

12/20/2005 9:14:23 PM (GMT Standard Time, UTC+00:00) #  | Comments [0] | 

Oggi ho speso un po' di tempo per fare il porting dalla beta2 alla RC1 di un sito ASP.NET 2.0. Non ci sono stati grandi problemi: se cambia il nome di una proprietà si stà veramente presto a capire qual è il nome nuovo, anche consultanto questa pagina. Ci sono però un paio di cambiamenti significativi la cui soluzione potrebbe non essere immediata, e che quindi ho deciso valesse la pena riportare nel blog. Io mi sono accorto di questi 2 cambiamenti solo ora, perchè le CTP intermedie tra la beta2 e la RC1 non sono mai riuscito ad installarle completamente con successo. Quindi può darsi che le cose fossero cambiate già prima.

Del primo cambiamento me ne sono accorto ricevendo la seguente eccezione all'esecuzione del codice per ottenere il profilo di un utente (quello corrente o un altro): {"Procedure or Function 'aspnet_Profile_GetProperties' expects parameter '@TimeZoneAdjustment', which was not supplied."}. Dopo aver cercato su Google per qualche minuto senza esito, mi sono creato un nuovo progettino web con la RC1 e ho controllato che i profili funzionassero. Il responso è stato ovviamente positivo. Allora sono andato a controllare la sproc incriminata, aspnet_Profile_GetProperties, nel DB che avevo nel progetto beta2, e nel progetto creato ex-novo con la RC1. Nel primo caso la sproc ha un terzo parametro chiamato @TimeZoneAdjustment, nel secondo caso il terzo parametro è @CurrentTimeUtc. E' quindi stato ovvio che il motivo dell'eccezione è che il codice della classe SqlProfileProvider aggiornata chiamava la stored procedure passando @CurrentTimeUtc, mentre la vecchia sproc presente nel DB si aspettava @TimeZoneAdjustment. La soluzione consiste nell'eseguire il wizard di aspnet_regsql.exe, selezionando l'opzione per eliminare il supporto ai servizi di ASP.NET 2.0 (membership, profili, logging, caching, personalization) dal database in questione. Fatto ciò si esegue nuovamente il tool riaggiungendo il supporto per tutti quelle funzionalità, e quindi di fatto ricreando tutti gli oggetti necessari per il loro funzionamento (tabelle, sproc, trigger), con lo schema aggiornato. A parte aver perso le informazioni sui pochi account di test che avevo creato (erano 4 record, quindi non valeva neanche la pena fare il backup) il risultato è stato perfetto.

Il secondo problema è che tutti i controlli ObjectDataSource collegati a un domain object e usati come data source dai vari controlli GridView e DetailsView sollevavano eccezione all'esecuzione dei comandi Update e Delete. Il problema qui era che nella beta2 i valori originali del record da cancellare/aggiornare (quindi ad esempio l'ID che identifica il record) venivano passati a parametri del metodo chiamati original_{NomeFieldQui}, ad esempio original_ID. Il prefisso poteva anche essere cambiato tramite la proprieta OldValuesParameterFormatString dell'ObjectDataSource, che per default era appunto impostata su "original_{0}". Tutte le mie classi usavano quindi questa convenzione per ricevere correttamente l'ID chiave nei metodi Update e Delete. Ora nella RC1 il valore di default di questa proprietà è {0}, ovvero il nome del campo senza più nessun prefisso. Ne consegue che l'ObjectDataSource non cercherà più un parametro nominato original_ID nella firma del metodo, ma ID e basta. Non lo trova e solleva eccezione. Le soluzioni possibili sono 2: o rinominate i parametri dei vostri metodi togliendo il prefisso (e lasciando quindi "id" o "ID", il controllo non è case-sensitive) oppure ripristinate il valore di OldValuesParameterFormatString su "original_{0}". Io ho preferito seguire la prima opzione per essere in linea con quanto fa di default VS.NET, e la cosa non ha preso comunque troppo tempo. Questa modifica al controllo ObjectDataSource è stata suggerita dal feedback di molti sviluppatori che hanno lavorato con le beta2, e che trovavano poco intuitivo dover nominare i parametri dei loro metodi con quel prefisso. Ecco l'annuncio semi-ufficiale da uno dei componenti del team di ASP.NET. Io sono in effetti d'accordo! Se dovesse comunque esserci la necessità di ottenere in input sia il valore corrente che quello originale di un campo, sarà comunque sempre possibile reimpostare un qualche prefisso per OldValuesParameterFormatString e avere il meccanismo funzionante esattamente come prima.

Tutto sommato il porting dalla beta2 alla RC1 è stato molto semplice, non ho fatto neanche in tempo a cominciare ad imprecare :-) Sempre che non ora spuntino sorprese poco piacevoli...ma sono ottimista!

10/25/2005 1:32:25 AM (GMT Daylight Time, UTC+01:00) #  | Comments [0] | 

Ero partito, tempo fa, con un post in cui parlavo di grafi navigazionali inseriti in un file xml e dati "in pasto" a UIPAB. La mia intenzione era di far partire una possibile discussione sulla base della mia esperienza (e leggere la vostra) in fatto di disaccoppiamento della UI dal resto dell'applicazione, poi ho pensato che sarebbe stato meglio scrivere qualcosa di più sostanzioso per dare una base più consistente di riflessione. L'articolo è online e lo trovate al seguente link

Link all'articolo "UIPAB2 e l'arte di disaccoppiare le GUI"

mi piacerebbe sapere quanti di voi utilizzano questo application block, se qualcuno lo ha customizzato aggiungendo delle features utili e tutto quello che vi viene in mente rispetto all'argomento. Ritengo che non sia affatto banale progettare uno strato di presentation "realmente" disaccoppiato dagli altri strati quindi mi interessa conoscere le problematiche incontrate (eventualmente superate) e dare, se possibile, qualche suggerimento in proposito, oltre naturalmente a ciò che ho scritto nell'articolo sperando che vi sia utile.

Buona lettura!

9/26/2005 12:16:24 PM (GMT Daylight Time, UTC+01:00) #  | Comments [0] | 

Una delle novità più sbandierate sia di SQL Server 2005, ma soprattutto di ASP.NET 2.0 è la possibilità di fare caching con dipendenze direttamente ai dati contenuti nel DB. Ovvero: tengo i dati in cache finchè non cambiano sul DB, invece che per un tempo determinato. Questo permette di risolvere 2 problemi della cache attuale:

  • Richiedere nuovamente i dati dal DB anche se in realtà non sono stati chiamati
  • I dati vengono cambiati poco dopo che sono stati messi in cache...ci resteranno magari per altri tot minuti, fornendo quindi dati vecchi all'applicazione

Troppo bello per essere vero, no? :-) Beh, vediamo...Intanto c'è da dire che il meccanismo funziona in modo diverso con SQL Server 7/2000 e con SQL Server 2005. Nel primo caso l'abilitazione al caching di ASP.NET con dipendenza ai DB deve essere fatta a mano, tramite il tool aspnet_regsql da riga di comando. Lo si chiama 2 o più volte: una prima per abilitare il supporto a livello di DB, e poi una volta per ciascuna tabella. Quello che questo tool fa è di creare delle nuove tabelle di supporto, trigger e stored procedure che tengono traccia delle modifiche (insert/update/delete) fatte sulle tabelle tenute sott'occhio. ASP.NET poi implementa un meccanismo di polling che ogni tot millisendi (la frequenza è configurabile da web.config) verifica se i dati in cache sono ancora validi, controllando se la tabella di supporto indica o meno che i dati sono cambiati dall'ultima query (internamente una stored procedure controlla se il contatore per quella tabella è stato incrementato dall'ultima volta). Da notare che la dipendenza è a livello di intera tabella, ovvero se io salvo in cache un record di una tabella, e qualcuno cambia un altro record della stessa tabella, la cache viene comunque invalidata.

Per quando riguarda SQL Server 2005 le cose sono molto diverse. Il nuovo engine è in grado di creare una indexed view per ogni query eseguita (che a differenza di una vista normale è una copia fisica dei valori), per la quale si è specificato che si vuole creare una dipendenza. Quando i dati restituiti dalla query eseguita cambieranno (sempre in seguito ad una insert/update/delete, ma anche altri comandi) SQL Server manderà una notifica al client che si era in precedenza registrato, spedendogli un messaggio tramite un nuovo servizio chiamato Service Broker. Tutto questo nuovo meccanismo si chiama Query Notifications. E' molto interessante, perchè permette di venire notificati solo quando i risultati della nostra specifica query cambierebbero se la query venisse eseguita nuovamente, cosa che quindi non accadrebbe se qualcuno modifica un record che non era incluso nei risultati precedenti. Se volete maggiori dettagli su come funziona il tutto dietro le quinte, potete fare riferimento a quest'ottimo articolo di Bob Beauchemin. In .NET la classe che permette di ricevere tali notifiche è SqlDependency, tramite il suo evento OnChange. Una volta che si ha un comando SqlCommand, ecco come usarla:

SqlDependency dep = new SqlDependency(cmd);
dep.OnChange += new OnChangeEventHandler(dep_OnChange);
...
void dep_OnChange(object sender, SqlNotificationEventArgs e)
{
   // ...
}

La classe SqlDependency è una classe di ADO.NET, e può quindi essere usata da qualsiasi applicazione. In ASP.NET poi c'è la nuova classe SqlCacheDependency, che internamente usa SqlDependency per sapere quando i risultati del commando ricevuto in input nel costruttore sono cambiati, e quindi invalidare l'elemento della Cache a cui fa riferimeno. Il tutto si traddurrebbe semplicemente come segue:

SqlCacheDependency dep = new SqlCacheDependency(cmd);
Cache.Insert("Categories", dsCategories, dep);

Fatta la dovuta introduzione, veniamo al punto del post...Per il sito che stò sviluppando al momento stò usando proprio SQL Server 2005, Express Edition. Ovviamente dopo aver letto articoli e articoli sulla cache, averne sentito parlare dappertutto ecc. ecc. mi sentivo anch'io parecchio eccitato a proposito, e non vedevo l'ora di usarla. Bene, ci provo e...non funziona! Il codice di test che ho isolato, usando direttamente SqlDependency in una applicazione WinForm, era il seguente:

private void Form1_Load(object sender, EventArgs e)
{
   using (SqlConnection cn = new SqlConnection(@"Data Source=.\SQLEXPRESS;
      AttachDbFilename=C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\northwnd.mdf;
      Integrated Security=True;User Instance=True"
))
   {
      SqlCommand cmd = new SqlCommand("SELECT * FROM Categories", cn);
      cn.Open();
      SqlDependency dep = new SqlDependency(cmd);
      dep.OnChange += new OnChangeEventHandler(dep_OnChange);
      SqlDataReader reader = cmd.ExecuteReader();

      while (reader.Read())
         textBox1.Text += reader["CategoryName"] + Environment.NewLine;
   }
}

void dep_OnChange(object sender, SqlNotificationEventArgs e)
{
   MessageBox.Show("Changed!");
}

Accadeva che l'evento veniva sollevato subito dopo aver eseguito il comando...ma non perchè i dati fossero cambiati, per qualche altro motivo. Ho cercato in lungo e in largo, fino a quando il grande Alex Homer (quello che ha insegnato ASP2 a generazioni di sviluppatori web :-) e autore tra l'altro di questo articolo proprio sulla cache) ha risposto ad una mia mail di richiesta spiegazioni. Nel mio codice c'erano fondamentalmente due errori:

  • Non è possibile usare * nelle query, ma bisogna elencare tutti i campi esplicitamente
  • Il nome delle tabella deve essere completo, ovvero qualcosa tipo dbo.Categories

Nella stored procedure che usavo nel mio caso reale indicavo già tutti i campi esplicitamente (sembre una buona regola), ma in effetti non usavo il nome completo della tabella. Queste comunque sono solo 2 delle molte regole che bisogna rispettare se si vuole poter usufruire delle Query Notifications. Le altre sono indicate nei Books Online di SQL Server 2005...oppure più semplicemente le trovate elencate in questa pagina. Le limitazioni sono davvero tante e significative: niene funzioni di aggregazione come COUNT e SUM, niente funzioni di ranking e paginazione (come la nuova ROW_NUMBER()), niente uso di tabelle temporanee, niente DISTINCT, niente query che restituiscono colonne di tipo text, ntext, o image, e altro ancora...In aggiunta ho scoperto (altra ora di tentativi ovviamente...) che la mia stored procedure non funzionava anche per un altro motico: avevo impostato SET NOCOUNT ON...

Ora, considerando che uso pesantemente la paginazione custom per i vari controlli GridView ecc. di ASP.NET, che ho bisogno di COUNT(*) sempre per supportare la paginazione, che molte delle mie tabelle hanno colonne ntext...praticamente il risultato è che non posso usare SqlCacheDependency da nessuna parte!!! Mi devo accontentare ancora del "vecchio" caching temporizzato, implementando in aggiunta un metodo per fare manualmente il purge dei dati in cache dopo aver eseguito una Insert / Update o Delete tramite i miei oggetti business. Non ho dubbi che ci siano molti casi di utilizzo perfetti, ma molto probabilmente molti meno di quanto tanti cercano di far credere in molti articoli e conferenze. Ah, un'ultima nota (anch'essa poco pubblicizzata), nel caso vogliate usare questa feature. Le SQL Dependencies di SQL Server 2005 NON dovrebbero ASSOLUTAMENTE essere utilizzate in almeno 2 casi:

  1. Se la tabella in questione viene aggiornata molto spesso. Ad esempio, nella mia tabella Articles c'è una colonna ViewCount che indica quante volte l'articolo è stato letto, e che quindi viene aggiornata ad ogni lettura. Il risultato sarebbe che la cache verrebbe invalidata praticamente ad ogni richiesta di un articolo...non solo annullandone l'effetto positivo, ma peggiornado parecchio la situazione, a causa del lavoro aggiuntivo per salvare i dati in cache, gestire la coda dei messaggi di notifica (in entrata e uscita) e pulire la cache...tutto per niente.
  2. Per query dinamiche risultanti da tanti filtri, e magari anche dipendenti dall'utente corrente. Questo meccanismo infatti non è fatto per poter supportare centinaia o migliaia di query diverse sullo stesso DB. Va bene se lo usate per una stored procedure che magari prende in input qualche filtro, ma che viene comunque chiamata allo stesso modo da gran parte degli utenti.

Detto questo, buoni esperimenti e buon divertimento :-)

Acknowledgements: thank you Alex for your kind explanation, you made my day! And thank you Bob for the great article on MSDN.

9/5/2005 1:44:01 AM (GMT Daylight Time, UTC+01:00) #  | Comments [0] | 

Per un sito al quale stò lavorando ho deciso di definire il layout principale completamente tramite DIV e CSS, piuttosto che usare le tabelle come ho sempre fatto (chiedo perdono ai puristi). Se ne parla dappertutto, ha effettivamente il vantaggio di separare i contenuti dalla loro rappresentazione, rende le pagine più accessibili, diventa possibile cambiare completamente disposizione e aspetto dei contenuti semplicemente cambiando il file CSS linkato, quindi perchè no? Se poi usate i temi di ASP.NET 2.0, i file .css presenti dentro la cartella del tema selezionato vengono automaticamente linkati all'interno della pagina...quindi vale la pena usarli anche solo per questo, anche se per qualche motivo non vi piacciono i file .skin. Presa la decisione ho cominciato a cercare qualche esempio in giro, dal momento che non sono un web designer e che non mi ero ancora mai scontrato con problemi di CSS avanzato. Si, proprio avanzato, perchè dopo essermi letto decine e decine di articoli mi sono reso conto che non c'è UNA soluzione giusta e definitiva...ci sono una miriade di hack per risolvere il bug di questo browser, il bug di quell'altro, ecc. ecc. Anche volendo prendere in considerazione solo IE5.5+ e FireFox (la mia situazione) i problemi restano comunque molti. I miei requisiti sono questi:

  • layout a 3 colonne, delle quali quelle laterali devono avere larghezza fissa, e quella centrale deve coprire la parte rimanente di larghezza
  • liquid layout, ovvero l'espansione o il restringimento al ridimensionamento del browser (ha i suoi svantaggi ma ha anche dei vantaggi)
  • le 3 colonne devono avere colore di sfondo diverso, e il colore deve arrivare fino all'inizio del footer, ovvero fin dove finisce la colonna più alta
  • presenza di un header e di un footer

Usando le tabella la soluzione è banale. Con DIV e CSS? Un incubo! Come dicevo in Internet si trovano montagne di articoli ed esempi (ad esempio questo, questo, questo, questo, questo, questo e quest'altro, ma basta fare una ricerca su Google per trovarne moltissimi altri), ma il 99% presenta uno o più di questi problemi:

  • Non funziona con liquid layout
  • Non funziona con colonne laterali dalla larghezza prefissata
  • Il testo della colonna più alta fluisce sotto quello delle colonne più basse
  • Il colore della colonna finisce non appena finisce il suo contenuto, invece di adeguarsi all'altezza della colonna più alta (non conosciuta a priori) e arivare fino al footer di chiusura

Poi chiaramente c'è il fatto che in IE magari sembra funzionare e in FireFox no, o viceversa (meno spesso). Fatto stà che gli esempi che ho provato funzionano solo se le colonne sono alte uguali, se mi va bene che il colore non arrivi fino in fondo, ecc. ecc. In altre parole: NON funzionano in casi reali :-) La soluzione più funzionante che avevo trovato fino ad ieri era la seguente:

  • Creare un DIV di header
  • Creare un DIV contenitore che abbia un margine destro di tot pixel.
  • Creare un DIV con posizionamento assoluto che sia addossato a destra e abbia larghezza tot pixel: questo definisce la colonna di destra
  • Dentro il primo contenitore crearne un secondo che abbia margine sinistro di tot pixel: questo definisce la colonna centrale, e lascia a sinistra lo spazio per l'altra colonna, assegnandole anche un colore del primo container
  • Creare un DIV con posizionamento assoluto, addossato a sinistra, e largo tot.
  • Creare in fondo il DIV footer, inizialmente nascosto (visibility = hidden)
  • Infine, usare javascript per calcolare l'altezza massima tra i DIV che rappresentano le tre colonne, assegnarla a ciasuno, e poi mostrare il DIV footer (questo si rende necessario per non mostrare il DIV che si sposta una volta che la pagina è già visibile)

Alla fine ce la si può cavare con una manciata di righe di javascript, quindi non sembra troppo drammatico...a parte il fatto che non capisco perchè devo essere costretto ad usare javascript per definire il layout! A quando pare però, leggendo qui e qui, è una soluzione adottata sul serio e che riesce concretamente a risolvere i problemi senza dover ricorrere a trucchi infiniti.

Stamattina ho trovato quest'altro articolo che NON usa JavaScript ma sembra comunque funzionare bene in entrambi i browser...ma anche questo si basa su diversi hack ovviamente, e non sembra semplicissimo. Per tornare alla premessa di questo post: non sono un web designer e quindi è possibilissimo che sia io a non conoscere abbastanza CSS e i vari browser, e che mi stia sfuggendo una soluzione più semplice ed elegante. Mi consola però il fatto che in giro si trovino migliaia di persone che si trovano nella stessa situazione, e che le soluzioni proposte sui vari siti (per web designer professionisti!) e riviste non sono poi tutte così efficaci ed esenti da problemi...forse quindi non è solo colpa mia :-) Per ora stò usando la soluzione con quel po' di javascript...ma se qualcuno di voi avesse da condividere un esempio che rispetti tutti i miei requisiti, che non usi trucchi astrusi e che funzioni bene con i diversi browser, mi farebbe proprio contento (e certo, entrerei a far parte di una schiera ristrettissima di eletti, aumenterebbe il mio valore :-)). Sfida impossibile? Sono perlomeno abbastanza sicuro che la soluzione non sia proprio semplice, banale e scontata...e anche se lo fosse, non potrebbe farmi altro che piacere essermi sbagliato ed aver imparato qualcosa di nuovo.

P.S.: da oggi avrò molto più rispetto per i web designer professionisti (ovvero chi non fa solo la grafica con PhotoShop, ma poi la converte in un layout HTML+CSS che rispetti standard vari e che sia compatibile con almeno i diversi browser recenti e diffusi)...soprattutto per la loro capacità di mantenere il lume della ragione in queste situazioni :-)

9/2/2005 11:29:52 AM (GMT Daylight Time, UTC+01:00) #  | Comments [0] | 


Uno dei nuovi controlli di ASP.NET 2.0 è DetailsView, che permette di mostrare un record in forma tabellare, un campo per riga, e solo un record per volta. Oltre alla visualizzazione sono supportate anche le operazioni di cancellazione, aggiornamento ed inserimento. I campi visualizzati sono definiti in una sezione <Fields>, in modo simile a come avviene per la DataGrid e la GridView nella sezione <Columns>, e per ciascuno è possibile specificare se è presente durante le modalità di aggiornameno ed inserimento. Ecco un esempio di dichiarazione del controllo, collegato ad un ObjectDataSource (non mostrato) per ricavare la sua sorgente dati:

 

<asp:DetailsView ID="dvwCategory" runat="server"

   AutoGenerateRows="False"

   DataKeyNames="ID"

   DataSourceID="objCurrCategory"

   AutoGenerateEditButton="True"

   AutoGenerateInsertButton="True"

   HeaderText="Category Details"

   OnItemCreated="dvwCategory_ItemCreated">

   <Fields>

      <asp:BoundField DataField="ID" HeaderText="ID"

         ReadOnly="True" InsertVisible="False" />

      <asp:BoundField DataField="Title" HeaderText="Title" />

   </Fields>

</asp:DetailsView>

 

Le proprietà AutoGenerateEditButton e AutoGenerateInsertButton impostate a True indicano che in fondo alla tabella verranno creati dei bottoni "Edit" e "New" che permettono all'utente di cambiare la modalità del DetailsView, passando ad esempio da modalità visualizzazione (ReadOnly) a modalità inserimento. Funziona tutto bene finchè non si cerca di personalizzare un po' l'interfaccia. Ad esempio in una delle mie pagine volevo che il DetailsView supportasse effettivamente l'inserimento e la modifica, ma volevo mostrare solo il bottone "Edit" in fondo al controllo -- avrei pensato io tramite un altro bottone in un'altra parte della pagina ad attivare la modalità inserimento, chiamando manualmente dvwCategory.ChangeMode(DetailsViewMode.Insert). Ho quindi provveduto a impostare AutoGenerateInsertButton su False - a quel punto però il cambiamento di modalità (ReadOnly -> Insert) funzionava, ma venivano a mancare i bottoni "Insert" e "Cancel", perchè anche la loro creazione è legata al fatto che AutoGenerateInsertButton sia True. La soluzione più semplice che ho trovato è di intercettare l'evento ItemCreated del DetailsView, cercare il bottone/link con CommandName uguale a "New" e nasconderlo nel caso venga trovato (semplicemente impostando la sua proprietà Visible su False). Non verrà sempre trovato, perchè nel caso il controllo sia in modalità inserimento il bottone non verrà comunque creato, e al suo posto ci saranno quelli per annullare o confermare la creazione del nuovo record. Ecco come tradurre in codice quando descritto:

protected void dvwCategory_ItemCreated(object sender, EventArgs e)
{
   if (dvwCategory.FooterRow != null)
   {
      foreach (Control ctl in dvwCategory.Rows[dvwCategory.Rows.Count - 1].Controls[0].Controls)
      {
         if (ctl is LinkButton)
         {
            LinkButton lnk = ctl as LinkButton;
            if (lnk.CommandName == "New")
               lnk.Visible = false;
         }
      }
   }
}

In questo modo il bottone "New" non sarà più visibile nella command bar standard del DetailsView, ma dal momento che AutoGenerateInsertButton vale True, i bottoni "Insert" e "Cancel" continueranno ad essere creati correttamente al momento opportuno. Dal momento che funziona non ho investigato nei minimi dettagli se ci fosse qualche alternativa, magari più elegante...se qualcuno avesse provato e risolto in maniera diversa, mi faccia sapere tramite un commento...

8/24/2005 10:46:25 AM (GMT Daylight Time, UTC+01:00) #  | Comments [0] | 

Se programmate in ASP.NET e vi tenete anche un minimo aggiornati (e ovviamente lo fate, altrimenti non vi trovereste in questo sito :-)) avrete sicuramente sentito parlare di AJAX (Asyncronous Javascript And XML) e Atals. AJAX è qualcosa che esiste da parecchi anni, anche se solo da un po' gli ho sentito appioppare questo nome. In pratica è la possibilità di usare Javascript lato client, assieme al componente XMLHttp, per inviare delle richieste a pagine sul server, ottenerne il risultato sotto forma di XML (ma anche stringa normale, con dei separatori custom se ci sono più informazioni), parserizzarlo in modo opportuno e sempre tramite javascript aggiornare la pagina corrente con le nuove informazioni recuperate. In pratica una sorta di aggiornamento parziale attuato senza che l'utente esegua dei postback. Esempi di utilizzo sono il rimpimento di una listbox di comuni quando l'utente sceglie una provincia da un'altra listbox, oppure la notifica di una nuova news o e-mail da leggere (come nella webmail di Libero). Come dicevo, la tecnologia non è certamente nuova, e si trova utilizzata molto pesantemente in diversi siti/applicazioni web. AJAX.NET è una libreria open source (infatti da qualche giorno è disponibile anche il suo sorgente) che permette di implementare molti di questi effetti semplificando parecchio il codice (sia lato client che lato server) necessario. Ne hanno già parlato diverse persone su diversi siti, quindi non mi dilungherò oltre.

AJAX è diventato molto più popolare da quando si è cominciato a parlare di Atlas, ovvero una tecnologia Microsoft che permetterà di semplificare drasticamente il lavoro necessario per implementare una serie di operazioni client-side molto avanzate. Tante funzionalità saranno impacchettate sotto forma di nuovi controlli server-side, quindi lo sviluppatore non dovrà far altro che trascinarli sulla pagina, impostare qualche proprietà, e premere F5 per provare il tutto. Leggete il post di presentazione di Scott Guthrie (e i commenti sotto, alcuni sono parecchio interessanti) per saperne di più. Atlas sarà presentato alla vicina PDC05, e dovrebbe essere rilasciato con ASP.NET 2.0.

Da quando si è cominciato a parlare di Atlas, tutti coloro che si occupano di ASP.NET i sono schierati da una parte o dall'altra: chi non vedo l'ora di avere Atlas tra le mani e riempire le proprie pagine con javascript che aggiorni qualcosa (qualsiasi cosa va bene :-)) e chi invece è scettico. Ad esempio, Daniele Bochicchio ieri ha scritto questo post aggregandosi decisamente al secondo gruppo. Daniele dice che quello che fa AJAX oggi (e quindi Atlas domani) non è standard, e non funziona su diversi client, tra cui i Pocket PC (e smartphone). Se ci infarcisono le pagine con roba non standard le renderanno inutilizzabili. Io sono decisamente d'accordo con quello che dice (del resto lui ne capisce di web, usabilità ecc. :-)), ma vorrei aggiungere qualcosa.

Con Atlas anche programmatori inesperti potranno creare con pochissimo sforzo effetti/funzionalità client-side avanzate. E' ragionevole pensare che molti ne abuseranno...diciamo la verità, è sempre bello impressionare un capo o un cliente con gli effetti speciali, no? :-) Certo poi magari viene fuori qualche rogna, ma poi...Questo atteggiamento costituisce decisamente un problema, è vero.
E' pur vero però che un programmatore con un po' di espierienza e serietà in più sarà in grado di capire quando una cosa serve a migliorare veramente l'usabilità, e quando invece la può minare, e decidere di conseguenza se, quando e come inserire AJAX all'interno delle proprie pagine. Aggiornare la lista dei comuni al cambiamento della provincia, è una cosa che ha decisamente molto senso, e la implementerei nella maggior parte delle situazioni. Controllare sul server se ci sono nuovi articoli, ogni 10 secondi, decisamente no!!! Anche perchè se uno si collega tramite GPRS magari va nella homepage di un sito e ci stà mezz'ora a leggere...spendendo molto più del previsto perchè magari dietro le quinte sono state effettuate 200 request/response per verificare la presenza di nuovi contenuti! E' vero anche il fatto che AJAX non è supportato da molti dispositivi, diventando quindi inutile per alcuni utilizzatori. Non solo, se una pagina può funzionare completamente SOLO tramite AJAX, allora la pagina può diventare addirittura inutilizzabile. Mi è piaciuta molto una frase di Daniele, che dice: "il progresso che uccide il progresso"...molto adatta alla situazione direi :-) Purtroppo Pocket IE è quello che è, e bisogna farci i conti (non a caso molti usano NetFront, che ha un miglior supporto per JavaScript, applet Java e frame). Non ho ancora provato se PIE è migliore in Windows Mobile 5 (i nuovi dispositivi che lo avranno on-board usciranno a partire da settembre/ottobre), ma dato che anch'io mi sono fatto convincere a comprare un i-mate JAM (con WM2003 SE) personalmente - come end-user - non mi cambierà nulla :-) Come sviluppatore invece non credo che la compatibilità con i palmari sia davvero un gran problema. Sono sempre stato dell'idea che un sito o anche una singola pagina fatta per un browser tradizionale spesso non sarà adatta per un palmare, senza opportune modifiche. Io consiglio spesso di creare due versioni diverse delle pagine principali del sito (homepage, pagina del singolo articolo/news, pagina dei contatti ecc.): la versione per palmare dovrà avere un menù semplicificato, niente immagini di sfondo, niente barre laterali, niente banner, niente javascript, niente frame, ecc. Alcune di queste cose si potrebbero attuare semplicemente applicando un diverso foglio di stile alla pagina, ma non tutte. Anche avere master page (in ASP.NET 2.0) diverse (da applicazre dinamicamente da codice) potrebbe essere un'ottima soluzione parziale. Nelle pagine per browser di alto livello userò AJAX, se serve, in quelle per PDA no. Semplice. Anche perchè, decidendo drasticamente di non utilizzare AJAX non dovrei utilizzare Javascript anche per tutti gli altri effetti grafici, quindi niente web part draggabili di ASP.NET, niente menu drop-down o treeview espandibili sul client, ecc. ecc. Suvvia, le web part draggabili sono troppo belle per essere cassate :-)

A proposito, volete un'idea di un software da sviluppare per fare i soldi? Che ne dite di una bella applicazionina ASP.NET che si agganci allo SharePoint locale e ne mostri i contenuti in forma semplice, senza tutto quel javascript e controlli ActiveX che usano, in modo da poter accedere alle informazioni aziendali anche da palmare o smartphone? Con il modello ad oggetti di SP si può fare senza troppo sforzo. Rendendo il tutto configurabile ne verrebbe fuori una bella cosetta.

Ah, quasi me ne stavo scordando: se veramente volete riempire l'applicazione di funzionalità in stile applicazione Windows...e il vostro target è una intranet...l'opzione di scrivere uno Smart Client è sempre più che valida! E troverete in Francesco un ottimo sostenitore :-)

8/19/2005 10:50:24 AM (GMT Daylight Time, UTC+01:00) #  | Comments [0] | 

O almeno questo è il titolo di questa pagina su MSDN :-) In realtà per ora io ne ho contate 47 di applicazioni di esempio, ma forse ne ne sono perse 3 perchè in fondo alla pagina c'è scritto "Coming soon - The remaining 51 samples are coming soon. Stay tuned." :-)

Ma non andiamo a pignolare, anche quello che c'è già è decisamente benvenuto! Le applicazioni sono fornite in C# o VB.NET e sono divise nelle seguenti categorie:

  • Base Class Libraries: come cambiare le ACL di un file, implementare animazioni su console, scaricare file da FTP, comprimere e decomprimere file, usare le generic collections, ricavare informazioni sui drive, usare la classe Stopwatch, eseguire il PING e qualche altra operazione di networking.
  • Data Access: query asincrone, uso e confronto di Datareader con DataSet, update batch, paginazione, bulk update, salvataggio e recupero di immagini dal DB, classi factory, uso di MARS, Notification Services, e UDT di SQL Server 2005.
  • Web Development: master pages, API e controlli di membership, profili, controlli menu e TreeView, web part, data binding con i vari componenti xxxDataSource.
  • Windows Forms: task asincroni, componenti BindingNavigator e BindingSource, estensioni alla DataGridView standard, i nuovi controlli MaskedTextBox, WebBrowser, StatusStrip, ToolStrip, SplitContainer e LayoutPanel.

Insomma, se ancora non avete dato un'occhiata a .NET 2.0 e VS.NET 2005, questi esempi pronti per essere eseguiti sono un'ottima occasione per vedere velocemente alcune delle novità introdotte. Complimenti per l'iniziativa, e come dice la pagina stessa: tenete d'occhio la pagina per gli ulteriori 51 (o 54?) esempi che hanno già promesso.

8/8/2005 1:12:48 PM (GMT Daylight Time, UTC+01:00) #  | Comments [0] | 
 
Feed di Blog2theMax
RSS 2.0 | Atom 0.2
Cerca nel blog
Archivio
<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910
Categorie

Powered by: newtelligence dasBlog 1.7.5016.2

 ©2004-2005 Code Architects S.r.l. - All rights reserved  Sign In