Aspettanto Atlas e SqlDependency, ho dovuto creare delle pagine che aggiornano, in automatico, il loro contenuto a fronte di modifiche alle tabelle da cui hanno prelevato i dati.
Il comportamento delle pagine in questione dovrebbe essere rappresentato in questo modo :
Grazie alla libreria Ajax.NET ho potuto effettuare le chiamate asincrone al metodo “.NET” lato server attraverso la funzione “wrapper” Javascript con l' overload che accetta un metodo di call-back.
Per quanto riguarda il controllo delle modifiche sulle tabelle, ho preso spunto dal funzionamento di SqlDependency in ASP.NET 2.0.
Ho creato una tabella [tblWatcher] con la seguente struttura :
- id
- tableName : nome tabella controllata.
- lastUpdate : data ultimo aggiornamento.
Per ogni tabella da monitorare applico il seguente trigger :
CREATE TRIGGER [TableName_Watcher] ON [dbo].[TableName]
FOR INSERT, UPDATE, DELETE AS
BEGIN
exec UpdateTableWatcher '[TableName]'
END
La SP che si occupa di aggiornare le informazioni :
CREATE PROCEDURE UpdateTableWatcher
(
@TblName AS VARCHAR(50)
)
AS
IF NOT EXISTS(SELECT tblName FROM tblWatcher WHERE tblName = @TblName)
INSERT INTO tblWatcher (tblName, lastUpdate) VALUES (@TblName, GETDATE())
ELSE
UPDATE tblWatcher SET lastUpdate = GETDATE() WHERE tblName = @TblName
GO
Codice della classe che si occupa della gestione delle informazioni sugli aggiornamenti :
[Serializable()]
public class TableWatcher
{
//Proprietà per incapsulamento omesse.
public string TableName;
public DateTime LastUpdate;
public bool HasChange;
public TableWatcher(string tableName)
{
TableName = tableName;
Watch();
HasChange = false;
}
public void Watch()
{
//Recupero data di aggiornamento.
currLastUpdate = TableWatcherDAL.GetLastUpdate(tableName);
HasChange = false;
//Controllo aggiornamenti.
if ( currLastUpdate > LastUpdate )
{
LastUpdate = date;
HasChange = true;
}
}
}
Codice della pagine per la logica di aggiornamento e la registrazione del tipo di dato per Ajax.NET.
public class AjaxTestPage : System.Web.UI.Page
{
protected System.Web.UI.WebControls.DataGrid grid;
public TableWatcher MyTableWatcher
{
get { return Session["Watcher"] as TableWatcher; }
set { Session["Watcher"] = value; }
}
private void Page_Load(object sender, System.EventArgs e)
{
Ajax.Utility.RegisterTypeForAjax(typeof(AjaxTestPage));
if ( ! IsPostBack )
{
PopulateGrid();
MyTableWatcher = new TableWatcher("myTable");
}
else
{
if ( MyTableWatcher.HasChange )
{
PopulateGrid();
MyTableWatcher.HasChange = false;
}
}
}
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]
public bool CheckUpdates()
{
MyTableWatcher.Watch();
return MyTableWatcher.HasChange;
}
private void PopulateGrid()
{
grid.DataSource = MyTableDAL.GetData();
grid.DataBind();
}
}
A questo punto non rimane altro che scrivere il codice "lato client" per l' esecuzione asincrona del metodo "lato server", marcato con l' attributo [AjaxMethod], che recupera le informazioni sullo stato di aggiornamento della tabella da monitorare.
Il pooling sulla tabella viene effettuato utilizzando il metodo Javascript setTimeout durante l' evento onLoad del tag body per chiamare la funzione "Ajax wrapper" del metodo "lato server" e nel metodo di call-back, in modo da creare un loop infinito di chiamate cadenzato dell' intervallo impostato.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<body MS_POSITIONING="GridLayout"
onload="setTimeout('AjaxPageTest.CheckUpdates(CheckUpdates_CallBack)', 10000);">
<script language="javascript" type="text/javascript">
function CheckUpdates_CallBack(response)
{
if ( response.value )
Form1.submit();
window.setTimeout('AjaxPageTest.CheckUpdates(CheckUpdates_CallBack)', 10000);
}
</script>
<form id="Form1" method="post" runat="server">
<div>
< SPAN>id="grid" Runat="server" AutoGenerateColumns="true"></asp:DataGrid>
</div>
</form>
</body>
</HTML>
powered by IMHO 1.2