Spesso, leggendo i newsgroups vedo che c'è una diffusa confusione sull'argomento UserControls e WebControls, non tanto in merito alla creazione dell'uno o dell'altro, ma soprattutto nell'utilizzo che hanno le due tipologie di controlli.

E' mia abitudine considerare in modo sostanzialmente diverso gli UserControl dai WebControl, e nel distinguerli ho adottato la seguente logica:

1) Lo UserControl è alla stessa stregua di una pagina. Questo non implica esclusivamente che vada "editato" in modo analogo, ma che esso possa fare accessi al database "diretti", ovvero senza dover esporre una proprietà datasource e acquisire i dati da visualizzare dalla pagina che lo contiene. Per questioni di prestazioni poi uso esporre nella pagina un oggetto "ConnectionManager" che mi consente di condividere la medesima connessione tra la pagina e lo UserControl contenuto.

2) Il WebControl, invece è una porzione di codice "completamente riutilizzabile". In soldoni, mentre la "riutilizzabilità" di uno UserControl ha uno scope di Applicazione, quello di un WebControl ha uno scope che esula dal dominio di una singola applicazione e non può essere diversamente perchè il riutilizzo in un'altra applicazione di uno UserControl ne comporta la duplicazione. Quindi i WebControls che sfrutto per mostrare dati adottano il consueto meccanismo di DataSource e DataBind().

Con questo criterio di lavoro mi sono sempre trovato bene e diventa immediatamente chiaro cosa si deve usare quando ci si trova nell'impasse. Si tratta di una mia assunzione e pertanto potrebbe essere soggetta a critiche, ma spero ceh qualcuno ne possa trovare beneficio.

powered by IMHO 1.2

 


La passeggiata odierna nel framework 2.0 è stata allietata da un bell'incontro: la classe ApplicationSettingsBase. Considero bello l'incontro perchè in questa classe ho ritrovato formalizzato quello che ormai è il mio abituale modo di incapsulare in una classe il file di configurazione dell'applicazione. Sono stato parecchio in giro, per il namespace System.Configuration, alla ricerca delle novità che lo riguardano, per decidere come comportarmi per la configurazione di .TRAQ. Da quello che vedo, le novità non sono poche, ma in gran parte si concentrano attorno a questa classe ed ai SettingsProvider che la supportano.

ApplicationSettingsBase in sostanza consente di esporre come istanza di una classe, una sezione del file di configurazione, trasformandone le chiavi in normali proprietà read/write. Quest'ultima affermazione fa anche comprendere che il framework 2.0 apporta una grossa novità ai file .config, ovvero la possibilità di modificarli a runtime. Ma facciamo un passo alla volta. Ecco una classe che estende ApplicationSettingsBase:

public sealed class DataProviderSettings : ApplicationSettingsBase
{
    
private static DataProviderSettings mInstance = new DataProviderSettings();

    
private DataProviderSettings()
    {}

    
public static DataProviderSettings Current
    {
        
get return mInstance; }
    }

    [ApplicationScopedSetting]
    
public string Type
    {
        
get return (string)this["Type"]; }
        
set this["Type"] = value; }
    }

    [UserScopedSetting]
    [DefaultSettingValue("10")]
    
public System.Int32 PageSize
    {
        
get return (System.Int32)this["PageSize"]; }
        
set this["PageSize"] = value; }
    }
}

In questa classe sono riassunte due delle maggiori novità che ho scovato. Innanzitutto occorre notare gli attributi ApplicationScopedSetting e UserScopedSetting, che rispettivamente consentono di dare un ambito di applicazione e di singolo utente alla proprietà. Questo significa che PageSize in particolare avrà un valore potenzialmente diverso per ogni utente dell'applicazione. La seconda novità, come anticipato poche righe fa è il metodo Save() per mezzo del quale è possibile rendere persistenti le modifiche apportate alle proprietà a runtime. PageSize, potrebbe essere una valida proprietà per memorizzare la dimensione massima di una pagina di record di una applicazione, secondo le preferenze dell'utente.

Ecco infine come deve essere realizzata la parte di configurazione in Xml:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup 
        
name
="applicationSettings" 
        
type
="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section 
          
name
="Elite.DotTraq.ConsoleTest.DataProviderSettings" 
          
type="System.Configuration.ClientSettingsSection, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /
>
    <
/
sectionGroup>
  <
/
configSections>
  <applicationSettings>
    <Elite.DotTraq.ConsoleTest.DataProviderSettings>
      <setting 
          
name
="Type" 
          
serializeAs
="String">
        <
value>System.Configuration.ClientSettingsSection, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value
>
      <
/
setting>  
      <setting 
          
name
="PageSize" 
          
serializeAs
="String">
        <
value>15</value
>
      <
/
setting>  
    <
/
Elite.DotTraq.ConsoleTest.DataProviderSettings>
  <
/
applicationSettings>
<
/
configuration>

L'esplorazione è appena cominciata, infatti ancora non ho avuto occasione di sperimentare l'uso dei SettingsProvider che a quanto ho capito dovrebbero consentire la lettura/scrittura di formati diversi dal consueto xml, e permettere di adottare media più inconsueti, come ad esempio un database. Ecco che in questo caso la proprietà di cui sopra potrebbe essere addirittura letta direttamente dal profilo utente nel database... ancora non so come, ma conto di capirlo a breve.

powered by IMHO


Oggi ho avuto l'occasione di testare la Microsoft Enterprise Library che è stata pubblicata da alcuni giorni, come segnalato da Lorenzo. L'occasione è venuta dal sito web che sto sviluppando e che vedrà la luce tra poche ore (spero).

Visto il post suddetto, e il fatto che per il sito avevo usato il DAAB 3.1, ho deciso di dare una chance alla Enterprise Library di sostituirsi al vecchio ApplicationBlock. Così, dopo una breve e "frugale" letta alla documentazione ho imbracciato il refactoring e ho cominciato l'opera certosina di ritoccare il codice nel modo più efficace.

La sorpresa è stata gradevole. E' davvero bastato sostituire poche righe di codice nello strato di logica dell'applicazione, e il sito è tornato a funzionare alla grande. Il nuove DAAB, astrae il database e si comporta a grandi linee come il vecchio Data Access Application Block, ma nel contempo fornisce un numero elevatissimo di nuove feature.

Prime fra tutte la gestione della configurazione che ora può essere suddivisa in file separati e può essere anche crittata. Inoltre il nuovo Application Block, così come tutti gli altri inclusi nella library crea una serie di Performance Counters che saranno di sicuro utilissimi in fase di debug e di tuning. L'unica accortezza è che nello sviluppo di un sito web si dovrà fare in modo che le chiamate ai Performance Counters non vengano eseguite, pena un errore causato dal tentato accesso al registry.

La MEL include al suo interno il supporto per database SqlServer, Oracle e DB2, la gestione automatica delle stringhe di connessione e una classe DatabaseFactory che leggendo dal file di configurazione "indovina" il provider di cui si ha bisogno.

Davvero un bel lavoro, talmente esteso che il paragone con il vecchio DAAB è davvero impressionante, ma la medesima sensazione la si ha anche sbirciando le altre librerie incluse nel progetto.

powered by IMHO 1.2


Dal blog di Roy Osherove ho scoperto un eccellente articolo sul SQL Injection, la dannosa pratica che permette di prendere possesso del database di siti o applicazioni realizzate male.

Articolo: SQL Injection Attacks by Example

La lettura è caldamente consigliata a chiunque scriva applicazioni web, perchè per la loro natura sono le più esposte a questo tipo di attacchi.

Infine un consiglio: fare uso dei SqlCommands e dei Parametri mette al riparo da gran parte dei possibili attacchi di Sql Injection.

powered by IMHO


Finalmente eccomi a pubblicare il lavoro svolto, e raffinato grazie alla collaborazione preziosa di Stefano Demiliani, che ha messo a disposizione il suo weblog in qualità di vittima sacrificale. Nel file che è possibile scaricare al termine del post, si può trovare tutto il necessario per aggiungere con semplicità un controllo anti-spam molto efficace e molto personalizzabile.

L'installazione è molto semplice e non richiede la ricompilazione di .TEXT:

  1. nello zip è riprodotta la struttura del folder web di dottext perciò è sufficiente porre i file così come vengono estratti nella relativa cartella
  2. occorre modificare il web.config per inserire il riferimento ad un httphandler che genererà l'immagini CAPTCHA. L'handler deve per forza essere il primo della lista tra tutti quelli già installati in .TEXT (grazie a Mighell per la segnalazione)
  3. in seguito bisogna modificare le skin personalizzate per aggiungere lo usercontrol all'interno del file PostComment.ascx, così come è indicato con alcuni commenti nello skin "white"

La licenza di questo controllo è di tipo D.W.Y.W.B.P.A.L.T.T.P. (Do whatever you want but post a link to this post)

E per un po' lo spam ce lo siamo tolti dai piedi.

Download: dottext_hip.zip (72KB)

powered by IMHO 1.1


Su cortese segnalazione di Lorenzo, vi annuncio che è in edicola il primo dei miei articoli appartenenti alla serie sugli Application Blocks, pubblicati da Infomedia su Computer Programming. Questo mese si parla di Data Access, con un utile esempio su come creare un piccolo ORM homemade che fa uso di reflection e stored-procedures oltre che naturalmente dell'Application Block.

Guai a chi non lo compra!

powered by IMHO


Una delle feature di maggior rilievo del Framework .NET è quella che consente di evitare il problema conosciuto sotto il nome di "Dll Hell". Fusion, così si chiama il meccanismo di ricerca e caricamento degli assembly ha introdotto un sistema molto flessibile per la definizione di un assembly e per il suo caricamento e versioning.

Nell'articolo Fusion Workshop, si può trovare una esauriente e dettagliata spiegazione di come funziona questo meccanismo.

powered by IMHO