Blog di LucaB

audio, video, disco

January 2008 - Posts

Non è arrivato per Natale ...
Dilbert Board Game

... ma stavolta le Poste Italiane non c'entrano.

Contrariamente alle mie aspettative, infatti, ci ha messo solo 12 giorni, anzi 6 giorni lavorativi, peccato che sia stato spedito quando il Natale era già passato.

Visti i precedenti, voglio sperare che il 2008 sia l'anno della svolta per le poste ...

 

Technorati Tags: ,

View blog reactions

Posted: Jan 10 2008, 12:05 AM by lucab | with no comments
Filed under:
Profile ASP.NET con un Web Application Project

Utilizzando i Web Application Project, mi è capitato un altro problema, stavolta con i profili di ASP.NET. A differenza di un WebSite, con i Web Application Project, infatti, non è possibile accedere da codice ad oggetti Profile.

Ciò è dovuto al fatto che gli oggetti Profile sono tipi generati runtime da ASP.NET, mentre nei Web Application Project i file sono compilati prima e non possono accedere a questi tipi.

Pertanto per accedere all'ASP.NET Profile è necessario scrivere una classe che faccia da proxy. Da questo indirizzo su codeplex è possibile scaricare un add-in per Visual Studio 2005 che genera una classe proxy strongly typed, la classe WebProfile, mediante la quale è possibile accedere all'ASP.NET Profile.

Per scaricare l'add-in:

ASP.NET WebProfile Generator

View blog reactions

Posted: Jan 08 2008, 11:30 PM by lucab | with no comments
Filed under:
Distinguere un postback sincrono da uno asincrono

Con l'utilizzo di AJAX, magari anche solo attraverso gli UpdatePanel, può capitare di voler distinguere tra un PostBack asincrono ed uno sincrono. Per farlo è sufficiente riferirirsi alla proprietà IsInAsyncPostBack dello ScriptManager.

Ad esempio, supponiamo di avere la seguente pagina Default.aspx:

<%@ Page Language="vb" AutoEventWireup="false" Codebehind="Default.aspx.vb"
Inherits="EsPB._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Prova PostBack</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <div> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <p> <asp:Label ID="Label1" runat="server" Text="PostBack:" /> </p> <p> <asp:Button ID="Button1" runat="server" Text="Asincrono" />
</p> </ContentTemplate> </asp:UpdatePanel> <asp:Button ID="Button2" runat="server" Text="Sincrono" /> </div> </form> </body> </html>

Per distinguere tra i due tipi di postback si può scrivere nel file Default.aspx.vb:

Partial Public Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load If Me.IsPostBack Then If ScriptManager1.IsInAsyncPostBack Then Label1.Text &= " Asincrono" Else Label1.Text &= " Sincrono" End If End If End Sub End Class

In questo modo premendo Button1, posto all'interno dell'UpdatePanel, si genera un postback asincrono e quindi si aggiunge la scritta "Asincrono" alla label nella pagina. Invece premendo Button2, che genera un normale postback (viene ricaricata l'intera pagina),  si aggiunge la scritta "Sincrono".

Quando si fa uso di MasterPage, bisogna far riferimento allo ScriptManager della pagina Master. Ad esempio

MasterPage.Master

<%@ Master Language="VB" AutoEventWireup="false" 
CodeBehind="MasterPage.master.vb" Inherits="EsPB.MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Prova PostBack con MasterPage</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <div> <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder> </div> </form> </body> </html>

DefaultContent.aspx

<%@ Page Language="vb" AutoEventWireup="false" 
MasterPageFile="~/MasterPage.Master" Codebehind="DefaultContent.aspx.vb"
Inherits="EsPB.DefaultContent" Title="Prova PostBack con MasterPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1"
runat="server"> <asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server"> </asp:ScriptManagerProxy> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <p> <asp:Label ID="Label1" runat="server" Text="PostBack:" /> </p> <p> <asp:Button ID="Button1" runat="server" Text="Asincrono" />
</p> </ContentTemplate> </asp:UpdatePanel> <asp:Button ID="Button2" runat="server" Text="Sincrono" /> </asp:Content>

DefaultContent.aspx.vb

Public Partial Class DefaultContent
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load If Me.IsPostBack Then Dim sm As ScriptManager = Me.Master.FindControl("ScriptManager1") If sm.IsInAsyncPostBack Then Label1.Text &= " Asincrono" Else Label1.Text &= " Sincrono" End If End If End Sub End Class

Technorati Tags: , , ,

View blog reactions

Posted: Jan 08 2008, 08:24 AM by lucab | with no comments
Filed under: , ,
Avviare il web server di sviluppo del framework .NET

Tempo fa avevo il problema di far lavorare Expression Web nella root del web server di sviluppo del framework, invece che sotto una directory virtuale. Avevo risolto lo stesso problema per Visual Studio 2005, ma questa volta però non sono stato capace di trovare nulla (né in rete né tra le opzioni del programma).

Allora mi è venuto in mente di aver letto questo post (per l'autore: hai visto che a qualcuno è servito? Wink), in cui si spiega come sia possibile avviare manualmente il web server di sviluppo, ossia il file WebDev.Webserver.exe che si trova nella directory %WINDIR%\Microsoft.NET\Framework\v2.0.50727

Le istruzioni per l'uso sono visualizzabili digitando da linea di comando:

%WINDIR%\Microsoft.NET\Framework\v2.0.50727\WebDev.Webserver.exe /?

che produce in output:

ASP.NET Development Server Usage:
WebDev.WebServer /port:<port number> /path:<physical path> [/vpath:<virtual path>]

port number:
[Optional] An unused port number between 1 and 65535.
The default is 80 (usable if you do not also have IIS listening on the same port).

physical path:
A valid directory name where the Web application is rooted.

virtual path:
[Optional] The virtual path or application root in the form of '/<app name>'.
The default is simply '/'.

Example:
WebDev.WebServer /port:8080 /path:"c:\inetpub\wwwroot\MyApp" /vpath:"/MyApp"

You can then access the Web application using a URL of the form:
http://localhost:8080/MyApp

Per risolvere il mio problema è bastato quindi lanciare il comando:

WebDev.WebServer /path:"c:\miosito"

(poiché avevo anche bisogno di lavorare sulla porta 80, oltre che nella root)

Sempre sul post di Paolo Ongari ci sono, invece, le istruzioni per un file batch completo.

View blog reactions

Posted: Jan 07 2008, 08:45 AM by lucab | with no comments
Filed under:
Compilare le classi di un progetto Web Application (dov'è finita l'App_Code?)

Da un po' di tempo sto provando ad utilizzare i Web Application Project di Visual Studio 2005 per la realizzazione di siti web. Ci sono, a mio avviso, diversi vantaggi in questo approccio, ad esempio la possibilità di gestire diversi file di configurazione. Però con l'uso sto scoprendo anche diverse "scomodità", almeno finché non si impara come fare.

Un problema che mi ha portato via un bel po' di tempo è stato la scomparsa dell'App_Code. Nei progetti Web Application non esiste la directory App_Code, ossia quella directory speciale, introdotta con ASP.NET 2.0 in cui basta mettere il codice sorgente delle nostre classi per trovarsele condivise per tutta l'applicazione. In pratica è come referenziare un assembly, solo che qui l'assembly è generato a runtime.

Poiché avevo la necessità di condividere delle classi tra le pagine di una mia applicazione web, ho testardamente provato ad aggiungere al progetto una cartella denominata App_Code. Ovviamente non compariva tra le voci di "Add ASP.NET Folder", ma una volta aggiunta (come cartella qualsiasi, dandole il nome "App_Code"), è stata visualizzata con l'icona tipica della cartella ASP.NET.

Ho quindi aggiunto le mie classi in questa cartella, ma anche dopo aver compilato, queste non erano condivise, l'intellisense di Visual Studio non le vedeva e forzandone l'uso nelle pagine, il compilatore dava errore.

Dopo un bel po' di ricerche su Internet, e di prove seguendo consigli sbagliati trovati in rete del tipo "metti le classi in App_GlobalResource" (stavolta stranamente non ho trovato nessuno che abbia dato la colpa a Vista Wink), finalmente sono arrivato alla banalissima soluzione:

è sufficiente mettere le classi che andrebbero nella cartella App_Code in una normale cartella[1] ed assicurarsi che ciascuno dei file delle classi (.vb o .cs) abbia impostato nelle proprietà, alla voce "Build Action", il valore "Compile" e non "Content", che sembra quello predefinito.

Magari l'avessi saputo prima...


[1] dovrebbe andare bene anche la cartella App_Code, che in un Web Application Project ha lo stesso valore di una cartella qualsiasi, però io non rischierei (anche se con piccole prove sembrava funzionare normalmente)

View blog reactions

Posted: Jan 06 2008, 03:03 PM by lucab | with no comments
Filed under: ,
Personalizzare lo SliderExtender Control dell'AJAX Control Toolkit

In questo post di Alessandro Gallo (segnalato da Scott Guthrie insieme a tanta altra roba interessante) si trova una descrizione dettagliata di come è fatto il layout e come sia possibile personalizzare lo SliderExtender attraverso i CSS.

Per dettagli:

SliderExtender layout and custom appearance

Technorati Tags: ,

View blog reactions

Come ottenere il valore di uno Uniqueidentifier dopo l'insert con SQL server

A quanto pare non esiste un modo per ottenere automaticamente il valore di un GUID dopo aver effettuato un INSERT con SQL Server (cosa possibile, invece, con una normale colonna identity attraverso SELECT @@IDENTITY in coda alla INSERT).

Bisogna perciò adottare altre tecniche, come ad esempio le tre suggerite in questo articolo. In breve si potrebbe:

  1. creare una Stored Procedure per l'INSERT che generi il valore per il GUID (invece che generarlo automaticamente assegnando la funzione NEWID() alla colonna), ne memorizzi il valore e lo resitutuisca dopo aver effettuato l'INSERT;
  2. aggiungere un trigger associato alla INSERT della tabella per cui ci interessa il GUID che restituisca il valore del GUID generato all'inserimento, magari fatto inmodo da utilizzare @@GUID (analogo a @@IDENTITY)
  3. non far generare automaticamente il GUID da SQL Server, ma generarlo sul client prima dell'INSERT e memorizzarne il valore.

Per tutti i dettagli:

How to retrieve the newly inserted GUID value?

Technorati Tags: , ,

View blog reactions

Posted: Jan 05 2008, 08:30 AM by lucab | with 2 comment(s)
Filed under:
Buon Anno

Buon 2008 a tutti.

View blog reactions

Posted: Jan 01 2008, 11:18 PM by lucab | with 4 comment(s)
Filed under: