venerdì 30 novembre 2007

Come creare un web control contenitore

Nel nostro controllo modifichiamo la fase di render a run-time inserendo un Javascript che emette l'HTML.

protected override void Render(HtmlTextWriter output){
output.Write("");
}


creiamo la classe per il rendering a design-time.

public class DesignTime : ControlDesigner{

ControlloCon FControllo;

public override void Initialize(System.ComponentModel.IComponent component){
this.FControllo = (ControlloCon)component;
base.Initialize(component);
}

public override string GetDesignTimeHtml() {
try{
if (FControllo.Text == string.Empty)
return GetEmptyDesignTimeHtml();
else
return "
" + FControllo.Text + "
";
}
catch(Exception ex){
return GetErrorDesignTimeHtml(ex);
}
}

protected override string GetEmptyDesignTimeHtml(){
return "
" + typeof(ControlloCon) + " " + FControllo.ID + "
";
}

protected override string GetErrorDesignTimeHtml(Exception e){
return CreatePlaceHolderDesignTimeHtml(e.Message);
}
}

Infine associamo il controllo alla classe di DesignTime.

[Designer("ControlloConDesignTime.DesignTime")]
public class ControlloCon: System.Web.UI.WebControls.WebControl{

martedì 27 novembre 2007

Insert nel dataset di VS2005

Usando i typed dataset di VS2005 come data layer si risparmia un sacco di tempo perchè si auto crea tutto uno strato di classi, metodi e query (per SQL: è questo l'ambiente che uso) che possono essere usati dallo strato business sovrastante.

Oggi ho scoperto una cosa alquanto allarmante, almeno fintanto che non lo si sa.

Mi focalizzo sul metodo di insert di una tabella del dataset. Si può sceglere tra text o stored procedure o table direct.
Nel caso si scelga text si può inserire il testo in due modi:
- usando il query builder (cliccando sugli appositi 3 puntini nel campo CommandText delle proprietà);
- inserendo a mano la query (magari facendo un copia/incolla da SQL manager).

C'è però una notevole differenza tra i due metodi: il primo infatti accoda "di soppiatto" un comando di select conforme con il comando di insert appena editato da noi.
Questo select è FONDAMENTALE in quanto serve per riportare i nuovi valori dal database al dataset che, in caso di assenza del select, rimane con i valori vecchi.
Il caso più eclatante si ha quando l'insert interessa delle righe di una tabella che ha un'indice auto-increment: auto-increment sia sul db (con step positivi) sia sul db (con step negativi)*.
In questo caso gli indici delle righe appena INSERITE sul db manterranno l'indice negativo ma cambieranno stato da added a unchanged. Ad un successivo cambio di stato in Modified si genererà una eccezione di mancanza di chiave primaria in fase di UPDATE, in quanto l'adapter farà affidamento sull'indice di riga rimasto negativo e disallineato dal db.



*: sul perchè è utile fare step negativi nel db per indici auto-increment rimando alla documentazione MS.

venerdì 23 novembre 2007

Problemi a design time (Win.NET)

Scenario:
- si sta sviluppando una interfaccia grafica di un form e si ha bisogno di creare un controllo separato da poi utilizzare nel form principale.
- non si ha l'auto increment nel buid.

Una volta aggiunto lo UserControl nel form, capita di trovarsi questo errore a design time :


per risolverlo basta coronare le proprietà pubbliche dello UserControl con il Custom Attribute
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

e il gioco è fatto.
Da quello che ho capito questo attributo dice al designer di non preoccuparsi di serializzare la proprietà e tirare avanti.
Quello che non mi spiego è perchè ha bisogno di serializzare questa proprietà che non è localizzabile e quindi non è esportata nel file di risorse. Forse è una cosa interna al designer.