Peppe Pace

Archive for the ‘.NET’ Category

Ottenere la tabella dell’oggetto che si vuole persistere con NHibernate

leave a comment »

public string GetPersistTable(ISession session, object persisted)
{
	AbstractEntityPersister persister = (AbstractEntityPersister)session.SessionFactory.GetClassMetadata(typeof(persisted));
	return persister.TableName;
}

Written by Peppe Pace

lunedì 31 dicembre 2007 at 14:17

Pubblicato su .NET, NHibernate, Sviluppo

Registrare codice javascript in controlli da utilizzare con e senza ASP.NET AJAX

leave a comment »

Avete realizzato dei webcontrol o usercontrol che fanno uso di javascript e volete utilizzarli sia con che senza la tecnologia ASP.NET AJAX. Istruzioni come queste:

....
Page.ClientScript.RegisterStartupScript(this.GetType(), "msg", "alert('Messaggio');", true);
....

non funzioneranno nel caso in cui il controllo sia in un contesto AJAX enabled, in quanto tutti i codici javascript vanno registrati tramite lo ScriptManager. Viceversa se ottimizzate il codice per usare gli oggetti con AJAX non potrete usarli in ambienti senza questa tecnologia. Che fare dunque per creare controlli universali?? Io, grazie al webcast dell’11/10/2207 ASP.NET 2.0 AJAX – Tips & Tricks di Andrea Dottor, sono giunto ad una soluzione che ritengo abbastanza buona. In una slide relativa al webcast è illustrato come richiamare lo ScriptManager o il ClientScript tramite reflection in base alla presenza o meno dell’assembly System.Web.Extension con questo codice:

MethodInfo RegisterClientScriptResourceMethod;
Type scriptManagerType = Type.GetType("System.Web.UI.ScriptManager, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", false);
// se diverso da null significa che è presente l’assembly System.Web.Extension nell’applicazione
if (scriptManagerType != null)
     RegisterClientScriptResourceMethod = scriptManagerType.GetMethod("RegisterClientScriptResource", new Type[] { typeof(Control), typeof(Type),typeof(string) });

if (RegisterClientScriptResourceMethod != null)
{
     // con ASP.NET AJAX, utilizzo ScriptManager
     RegisterClientScriptResourceMethod.Invoke(null, new object[] { control, type, resourceName });
}
else
{
     // senza ASP.NET AJAX,utilizzo ClientScriptManager
     control.Page.ClientScript.RegisterClientScriptResource(type, resourceName);
}

Questo codice è valido solo per il metodo RegisterClientScriptResource dunque perchè non generalizzare ulteriormente?? Rispondendo a questa domanda viene fuori questa classe. Usando i metodi statici in essa implementati è possibile includere codice javascript nei vostri controlli senza preoccuparsi dell’ambiente (con o senza AJAX) in cui vengono utilizzati. Non tutti i metodi sono implementati, lascio a voi ulteriori implementazioni e mi raccomando se la migliorate fatemelo sapere.

Written by Peppe Pace

martedì 4 dicembre 2007 at 1:00

Pubblicato su .NET, Sviluppo

Autocomplete=”off” per le textbox “autocompletate” con ASP.NET Ajax

with one comment

Ogniqualvolta si implementa l’AutocompleteExtender per una TextBox è necessario disabilitare l’autocompletamento del browser, che tante volte è utile ma non in questo caso. Per farlo però non basta utilizzare la proprietà AutoCompleteType delle TextBox settandola a Disabled perchè questo settaggio funziona solo su Internet Explorer, mentre su altri browser no. Che fare allora? Bisogna aggiungere la coppia attributo/valore autocomplete=”off” ad ogni TextBox, cosa alquanto fastidiosa se le TextBox sono tante, e se poi se ne dimentica qualcuna? Per risolvere quest’annosa questione ho implementato nella classe da cui faccio derivare poi le singole pagine il seguente codice:

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            DisableBrowsersAutocomplete(this);
        }

        /// <summary>
        /// Cerca nel controllo indicato tutti i controlli di tipo Textbox per cui è stato implementato l'autocomplete ed aggiunge l'attributo autocomplete="off"
        /// </summary>
        /// <param name="root">Il controllo in cui effetturare la ricerca delle textbox</param>
        private void DisableBrowsersAutocomplete(Control root)
        {
            if (root is AutoCompleteExtender)
            {
                AutoCompleteExtender ace = (AutoCompleteExtender)root;

                string textboxID = ace.TargetControlID;

                if (!string.IsNullOrEmpty(textboxID))
                {
                    TextBox textbox = this.FindControlRecursive<TextBox>(ace.Parent, textboxID);
                    if (textbox != null)
                    {
                        textbox.Attributes.Add("autocomplete", "off");
                    }
                }
            }
            else if (root.HasControls())
            {
                foreach (Control ctrl in root.Controls)
                {
                    DisableBrowsersAutocomplete(ctrl);
                }
            }
        }

        /// <summary>
        /// Cerca il controllo corrispondente all'Id indicato come parametro, cercando ricorsivamente all'interno del controllo indicato
        /// Per questa funzione utile anche in altre occasioni non ringraziate me bensì Andrea Boschin (http://blog.boschin.it/) e questi 2 post:
        /// http://blogs.ugidotnet.org/PenPal/archive/2006/01/25/33693.aspx
        /// http://blogs.ugidotnet.org/PenPal/archive/2006/01/31/34025.aspx
        /// </summary>
        /// <typeparam name="T">Il tipo del controllo da cercare</typeparam>
        /// <param name="root">il controllo da cui partire con la ricerca</param>
        /// <param name="id">l'id del controllo da cercare</param>
        /// <returns>il controllo trovato oppure il valore di default per il tipo che si cercava</returns>
        public T FindControlRecursive<T>(Control root, string id) where T : Control
        {
            if (root.ID == id && root is T)
                return root as T;

            if (root.HasControls())
            {
                foreach (Control child in root.Controls)
                {
                    T foundControl = FindControlRecursive<T>(child, id);

                    if (foundControl != null)
                        return foundControl;
                }
            }
            return default(T);
        }

Probabilmente la soluzione è migliorabile, magari ce ne sono di più eleganti, sicuramente questa funziona.Spero e credo che il codice sia abbastanza chiaro, se non lo fosse sono qui pronto alle vostre domande, invettive, suggerimenti.

Written by Peppe Pace

lunedì 26 novembre 2007 at 20:39

Pubblicato su .NET, Sviluppo

Programmazione e festività

leave a comment »

Chi non ha mai avuto la necessità di sapere se una determinata data era un giorno lavorativo o meno? Facile trovare l’elenco delle festività italiane su wikipedia (se l’internazionalizzazione non è un requisito indispensabile) ma come fare con la Pasqua? La Pasqua è la domenica successiva al primo plenilunio successivo all’Equinozio di Primavera. Da questa definizione è possibile risalire ad un algortimo implementabile che consenta il calcolo della data? Certo che no. Approfondendo le ricerche si approda a questa pagina, dove è descritto l’algoritmo di Oudin-Tondering per il calcolo della data della Pasqua, che è facilmente implementabile con una semplice funzione. Ecco la mia implementazione in C#:

public DateTime GetEaster(int year)
{
    int g = year % 19;
    int c = year / 100;
    int h = (c - c / 4 - (8 * c + 13) / 25 + 19 * g + 15) % 30;
    int i = h - (h / 28 ) * (1 - (29 / (h + 1)) * ((21 - g) / 11));
    int j = (year + year / 4 + i + 2 - c + c / 4) % 7;
    int l = i - j;
    int month = 3 + (l + 40) / 44;
    int day = l + 28 - 31 * (month / 4);

    return new DateTime(year,month,day);
}

Definita questa funzione diventa facile definire la funzione che in ingresso riceve una data e restituisce un valore booleano che indica se è una data festiva o comunque considerata tale e quindi non lavorativa:

public bool IsHoliday(DateTime day)
{
bool isHoliday = false;
DateTime[] festivita = {
new DateTime(day.Year, 1, 1),//Capodanno
new DateTime(day.Year, 1, 6),//Epifania
GetEaster(day.Year),//Pasqua
GetEaster(day.Year).AddDays(1),//Lunedì dell’Angelo
new DateTime(day.Year, 4, 25),//Festa della Liberazione
new DateTime(day.Year, 5, 1),//Festa dei lavoratori
new DateTime(day.Year, 6, 2),//Festa della Repubblica
new DateTime(day.Year, 8, 15),//Ferragosto
new DateTime(day.Year, 11, 1),//Ognissanti
new DateTime(day.Year, 12, 8 ),//Immacolata Concezione
new DateTime(day.Year, 12, 25),//Natale
new DateTime(day.Year, 12, 26)//Santo Stefano
};

for (int i = 0; i < festivita.Length; i++) { isHoliday = isHoliday || (day.CompareTo(festivita[i]) == 0); } return (isHoliday || ((day.DayOfWeek == DayOfWeek.Saturday) || (day.DayOfWeek == DayOfWeek.Sunday))); }[/sourcecode] Queste le funzioni, sono semplici e sicuramente migliorabili e sono a vostra disposizione. Buon lavoro

Written by Peppe Pace

venerdì 19 ottobre 2007 at 13:31

Pubblicato su .NET, Sviluppo

Percorsi UNC e Visual Studio 2005

leave a comment »

Scenario
Sviluppo di un’applicazione web con Visual Studio 2005, la directory con la soluzione è contenuta all’interno di unità di rete o è semplicemente condivisa su un altro computer.

Problema
Avete appena aggiunto il riferimento ad una libreria che vi risolverà tutti i vostri problemi ma compilando la soluzione viene sollevata la seguente eccezione relativa alla sicurezza e più precisamente relativa a: System.Web.AspNetHostingPermission.

Causa
La libreria utilizzata si trova su un computer remoto quindi l’IDE nel compilare la soluzione, a causa delle limitazioni previste per il codice condiviso in rete, solleva l’eccezione anche se poi il tutto funziona accedendo all’applicazione sul web.

Soluzione
Non potete prescindere dall’uso della libreria? Dovrete configurare .NET in modo tale da dare i permessi di FullTrust al percorso UNC. Ecco come fare:

  1. Accedere al pannello di configurazione del Framework: Start-> Pannello di controllo-> Strumenti di amministrazione -> Microsoft .NET Framework 2.0 Configuration
  2. Seguire il seguente percorso: Console Root -> Microsoft .NET Framework 2.0 Configuration -> My Computer -> Runtime Security Policy -> Machine -> Code Groups -> All Code
  3. Cliccare con il destro sulla voce All Code e selezionare New…
  4. Lasciare selezionata la voce Create a new code group, riempire la casella Name con un nome identificativo e cliccare su Next
  5. Nel combobox selezionare URL, nell’omonima casella indicare il percorso UNC della directory della soluzione nel seguente formato: file://\\[nomecomputer]\[percorsodirectorysoluzione]\* e cliccare su Next
  6. Selezionare la voce Use exisiting permission set, nella combobox scegliere FullTrust, cliccare su Next e infine su Finish
  7. Riavviare Visual Studio

Fatto tutto ciò, rieseguendo la compilazione non dovrebbero più venire sollevate eccezioni.

Written by Peppe Pace

venerdì 19 ottobre 2007 at 13:04

Pubblicato su .NET, Guida, Sviluppo

GestPayCrypt, .Net e Aruba

with 11 comments

Obiettivo
Sviluppare la procedura di pagamento con carta di credito attraverso l’apposito del servizio di Banca Sella, utilizzando ASP.NET per un sito in hosting su Aruba, senza problemi.

Fase 1 – Studio dell’ambiente di hosting
Accedendo all’area di assistenza di Aruba si scopre facilmente che è fornito supporto all’implementazione del servizio di Banca Sella e ci sono anche delle indicazioni per l’implementazione in ASP.NET.

Fase 2 – Studio del servizio di Banca Sella per il pagamento con carta di credito
All’indirizzo www.sellanet.it una volta registrati è possibile trovare tutto il materiale (specifiche, materiale da scaricare, esempi) che riguardano il servizio di pagamento e qui si scopre che esso è basato su un oggetto COM e che non esiste un porting per .NET, nulla di preoccupante visto che aggiungendo il riferimento all’oggetto COM nel progetto in Visual Studio 2005 viene generato direttamente l’assembly che fa da wrapper all’oggetto COM.

Fase 3 – Impostazione dell’ambiente di sviluppo e problema
Scaricata la dll del servizio l’ho copiata dentro la directory c:\windows\system32 e da prompt l’ho registrata con il comando regsvr32 GestPaycrypt.dll. Fatto ciò ho aggiunto il riferimento alla dll nel progetto su cui sto lavorando, copio il codice di esempio messo a disposizione da Aruba nella pagina che rimanderà alle pagine di Banca Sella, compilo ed ecco la sorpresa:

Errore 102 Impossibile trovare il tipo o il nome dello spazio dei nomi ‘GestPayCrypt’. Probabilmente manca una direttiva using o un riferimento a un assembly

Cosa è successo? Un incoveniente fastidioso. Visual Studio attraverso le informazioni contenute nella dll, nel creare il wrapper della libreria di Banca Sella ha creato una classe con il nome GestPaycrypt che è differente da quella presente sul server di Aruba di cui è fornito il codice di esempio che invece è GestPayCrypt (una c minuscola al posto di quella maiuscola)

Soluzione del problema
La soluzione di questo incoveniente è più facile da attuare che da spiegare (o forse sono troppo lagnuso…) quindi vi invito a scaricare direttamente l’assembly modificato e corretto*. Per i più curiosi: per effettuare la correzione sono partito dall’assembly creato da Visual Studio e armato di Reflector sono risalito ai sorgenti, li ho modificati e li ho ricompilati così da avere il nuovo assembly.
Implementazione servizio pagamento
Eh no! Questo ve lo fate da soli! 😛

* NB: questo assembly è da utilizzare solo per ottenere la corretta compilazione del progetto web in locale e consentire lo sviluppo della procedura compatibilmente all’ambiente GIA’ PRESENTE sull’hosting di Aruba, non è da usare in fase di produzione. Non è coperta da assistenza di Banca Sella e non mi assumo nessuna responsabilità per eventuali malfunzionamenti o danni che possa creare.

Written by Peppe Pace

venerdì 18 maggio 2007 at 20:03

Pubblicato su .NET, Sviluppo

Utilizzare SqlRoleProvider, SqlMembershipProvider e SqlProfileProvider su hosting Aruba

with 107 comments

Supponiamo che avete realizzato un’efficientissima e bellissima webapp che utilizza i sopraelencati provider e che adesso vogliate pubblicarla sullo spazio che avete acquistato presso Aruba. Effettuate l’FTP dei file, caricate il database sul server Ms SQL di Aruba, fate le necessarie modifiche al web.config e provate a visualizzare il sito. Risultato? Un errore mai visto prima appare sul vostro schermo:


Could not find stored procedure ‘dbo.aspnet_CheckSchemaVersion’. Descrizione: Eccezione non gestita durante l’esecuzione della richiesta Web corrente. Per ulteriori informazioni sull’errore e sul suo punto di origine nel codice, vedere l’analisi dello stack.
Dettagli eccezione: System.Data.SqlClient.SqlException: Could not find stored procedure ‘dbo.aspnet_CheckSchemaVersion’.


Cosa è successo? Nulla di irrecuperabile, ma abbastanza fastidioso. L’implementazione di Microsoft dei tre provider ha, sia nelle classi che nel codice SQL, “embeddato” il riferimento all’utente dbo, che sicuramente non è l’utente che Aruba vi ha fornito per accedere al loro server MS SQL. Come ovviare alla cosa allora? Basta seguire alcuni semplici passi:

  • Scaricate da qui i sorgenti dei tre provider
  • Rimuovete dai sorgenti tutti i riferimenti all’utente dbo con il semplice ma efficace Trova&Sostituisci
  • Compilate i sorgenti così da avere a disposizione un nuovo assembly ovvero ProviderToolkitSampleProviders.dll
  • Copiate l’assembly nella directory Bin della vostra webapp
  • Nel web.config nella riga corrispondente alla definizione di ognuno dei tre provider sostituite il contenuto dell’attributo type con il seguente : “Microsoft.Samples.<Nome_della_classe_del_provider>, ProviderToolkitSampleProviders”
  • Esportate gli script di viste e stored procedure, dal vostro db in locale, relative ai tre provider e rimuovete anche in questi script ogni riferimento all’utente dbo.
  • Sostituite con questi nuovi script le viste e le stored procedure presenti sull’hosting di Aruba
  • Non dimenticate di copiare i record contenuti nella tabella aspnet_SchemaVersions dal vostro db a quello su Aruba

Fatto tutto ciò potrete godervi la vostra applicazione web.

Written by Peppe Pace

lunedì 5 marzo 2007 at 21:18

Pubblicato su .NET, Guida, Sviluppo