Archivio

Articolo taggato ‘asp.net’

Deserialize Dictionary

January 21st, 2009 No comments

Dopo infiniti debug ad una applicazione infimissima in c# abbiamo finalmente trovato la soluzione, utilizzando il miglior debug e solution solver in commercio. E’ un prodotto assolutamente gratis e usabile da tutti, in pieno stile 2.0: si chiama Google.

Ringrazio subito Miha Markič e Brent Challis per la preziosa collaborazione, anche senza che io gli avessi detto niente. Devono essere dei veri e propri guru :)

 

Problema

Non si riescie a deserializzare (da binario) un oggetto di tipo Dictionary, o meglio una classe che eredita un oggetto di tipo Dictionary<(Of <(TKey, TValue>. L’errore del compilatore (VS9 in ambiente .net 2.0) è:

{"Impossibile trovare il costruttore richiesto per deserializzare un oggetto di tipo '<Namespace>.<ClassName>'."}

 

Soluzione

L’oggetto Dictionary è serializzabile in quanto implementa l’interfaccia ISerializable. Al suo interno (classe base) è definito però un costruttore necessario alla deserializzazione:

protected Dictionary(SerializationInfo info, StreamingContext context);

E’ quindi necessario che nella nostra classe, che eredita Dictionary, quindi tutti i  suoi metodi ma non i suoi costruttori, implementare tale costruttore basato su classe base in questo modo:

public <ClassName>(SerializationInfo si, StreamingContext sc):base(si,sc){}

 

E il gioco è fatto! Grazie Franz per l’appoggio morale, e riprendi in mano il tuo blog che era eccezionale!

The located assembly’s manifest definition does not match the assembly reference

December 1st, 2008 No comments

Se state sviluppando applicazioni .NET, utilizzando componenti c++ in formato DLL e durante il vostro cammino trovate frasi tipo:

  • The located assembly’s manifest definition does not match the assembly reference
  • failure adding assembly to the cache: the module was expected to contain an assembly manifest

Non allarmatevi e non buttate al vento milioni di ore cercando su blog, forum e supporti che danno indicazioni di ogni tipo. Se avete ogni DLL correttamente firmata, con nomi sicuri, e assoluta corrispondenza delle DLL di sviluppo con quelle sul server, la prima cosa che potete fare è installare sul server il RUNTIME c++.

Se state usando Visual Studio 2008 installate il Runtime 2008, altrimenti installate il Runtime 2005. In questo modo se Microsoft rilascia degli aggiornamenti delle DLL le aggiorna automaticamente con Windows Update.

Have a programming day :)

 

Asp.Net: zip component for free

June 19th, 2008 2 comments

Da qualche tempo utilizzo un componente free anzi opensource per creare e gestire file Zip in ASP.NET.  Il componente / libreria si chiama SharpZipLib, e fino a stamattina andava alla perfezione.

Il mio più grande errore è stato cercare info all’estero su questo componente. Comunque con un po’ di fatica, l’ho implementato e gli zip li fa proprio per bene. Il problema però, non appena il mio prodotto ha iniziato a essere utilizzato bene, è saltato subito all’occhio (del sistemista).

Con file di grosse dimensioni finiva la RAM e il server piazzava un bel memory overflow, o più esattamente: (mscorlib)Insufficient system resources exist to complete the requested service

Disperato, e quasi convinto di dover trovare un altro componente, fortunatamente ho pensato agli amici di HTML.it, e tramite loro ho scoperto il sito .Net2theMax.it!

La spiegazione di tutte le righe la trovate su .net2theMax.it, io voglio solo fare un appunto su qualche riga. La mia precedente procedura prendeva il file da comprimere, e lo sbatteva in un array di byte (più o meno) in questo modo:

byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);

Praticamente tutto il file in memoria. In una unica botta. Ma se il file è parecchi mega? Fortunatamente la soluzione non era cambiare componente ma sistemare il buffer:

while (fs.Position < fs.Length)
{
bytesRead = fs.Read(mBuffer, 0, mBuffer.Length);
zip.Write(mBuffer, 0, bytesRead);
crc.Update(mBuffer, 0, bytesRead);
}

E il mondo per un po’ a reiniziato a sorridere. Grazie a tutti e al mio amico Franz.

Categorie: Critiche Tag: , , , , , ,

(mscorlib)Insufficient system resources exist to complete the requested service

June 19th, 2008 No comments

Ho creato un’applicazione .net che prende in carico dei file e poi li elabora e li risalva in HD. Il problema è che tali file devono essere gestiti completamente in memoria, e che con grandi file, il buon Windows 2003 risponde:

(mscorlib)Insufficient system resources exist to complete the requested service

Pare che mamma microsoft dia però una soluzione (kb 304101):

 

1 Click Start, click Run, type regedit in the Open box, and then click OK.
2. Locate and then click the following registry subkey:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management
3. On the Edit menu, point to New, and then click DWORD Value.
4. Type PoolUsageMaximum as the entry name, and then press ENTER.
5. Right-click PoolUsageMaximum, and then click Modify.
6. Click Decimal.
7. In the Value data box, type 60, and then click OK.

Important

Use 60 as your initial value. If your backup does not succeed, use 40 as your value. If that does not work, you must change the behavior of your backup program to reduce the demand of paged pool. If the value works, you may want to increase the value by approximately 25 percent until the backup does not work. If the backup is unsuccessful, use the second registry setting that is described in this article.
Make sure that the value for this registry setting is not more than 60.
If you are using the /3GB switch, use 40 as your initial setting. Note that this value is a percentage value.
8. Quit Registry Editor.
9. Restart your computer.

Ciao!

Verificare se ci sono nodi checkati

April 17th, 2008 No comments

Una velocissima funzione in c# per ASP.NET che verifica se ci sono noti checkati all’interno di un ramo di un Tree.
Purtroppo c# mette a disposizione CheckedNodes solamente come proprietà del Tree, e non partendo da un nodo intermedio o periferico.

La funzione è semplicissima e sfrutta la ricorsività, la somma booleana e la proprietà Checked di un Node.

 1 bool NodeHasChecked(Node myNode)
 2     {
 3         bool res;
 4         res = myNode.Checked;
 5         foreach (Node thisNode in myNode.Nodes)
 6         {
 7             res = res || NodeHasChecked(thisNode);
 8         }
 9         return res;
10     } 

Et voilà, le jeux sont fait.

Categorie: Critiche Tag: , , ,

Generare un numero random in c#

March 26th, 2008 4 comments

Per generare un numero random in ASP.NET (c#) dobbiamo istanziare un istanza dell’oggetto RANDOM (System.Random):

Random RandomClass = new Random();

A questo punto  possiamo scegliere se creare un numero casuale tra 0  e 2.147.483.647:

int RandomNumber = RandomClass.Next();

oppure se dare dei parametri per la generazione di un numero da … a…:

int RandomNumber = RandomClass.Next(4, 14);

Se invece vogliamo solamente stabilire il massimo numero generabile possiamo usare:

int RandomNumber = RandomClass.Next(14);

 

La stessa cosa vale per la generazione di un numero float, cambiando però il metodo che chiamiamo:

double RandomNumber = RandomClass.NextDouble();

 

Le specifiche dell’oggetto complete su MSDN.

Categorie: Critiche, InfoTech Tag: , ,

Impersonate a Thread in Asp.net

March 18th, 2008 No comments

Claudia RossiAsp.net da la possibilità di gestire l’identità con cui viene eseguito un sito. Farlo in modo generico è molto semplice.
Nel file web.config inseriamo queste due righe di XML

<identity impersonate="true"
userName="xxx"
password="yyy"/>

Il problema è che se noi lanciamo un Thread asincrono, questo per motivi di sicurezza non viene eseguito dall’utente che abbiamo dichiarato noi, ma viene eseguito dall’utente di default del server (ASPNET).

A questo punto le scelte sono 2: cambiare il comportamento dell’intero server o fare una "furbata".
Per cambiare il comportamente dell’intero server bisogna modifcare il file aspnet.config presente nella directory:
%Windir%Microsoft.NET\Framework\{Version Number\

Aggiungendo:

<configuration> <runtime> <alwaysFlowImpersonationPolicy enabled="true"/> <legacyImpersonationPolicy enabled="false"/> </runtime> </configuration>

Per fare una cosa fatta meglio possiamo procedere in questo modo.
Premesso che abbiamo già definito l’utente che esegue il processo (nel web.config) dobbiamo fare in modo di comunicare al Thread di usare tale utente, e per questo utilizziamo il metodo Impersonate della classe windows.security.principal.WindowsIdentity.

Quindi creiamo l’oggetto  da passare al Thred, comprensivo di un oggetto WindowsIdentity, quindi all’interno del Thred facciamo una Impersonate(). Vediamo il codice.

[...]
//preparo l'oggetto per i parametri
MyThreadObj zc = new MyThreadObj();
zc.a = "Denis Milani";
zc.b = "Rosaria Cannavò";
zc.c = "Sara Varone";
//setto l'identity
zc.wi = System.Security.Principal.WindowsIdentity.GetCurrent();         
//lancio il thread
Thread t = new Thread(new ParameterizedThreadStart(ThreadProc));
t.Start(zc);
[...]
private void ThreadProc(object o)
{
   //lancio l'impersonate
   String me;
   MyThreadObj zc = (MyThreadObj)o;
   //eseguo impersonate
   WindowsImpersonationContext impersonationContext = zc.wi.Impersonate();
   me = WindowsIdentity.GetCurrent().Name;
   //recupero il tipo di oggetto corretto
   [...operazioni del Thread... ]
   impersonationContext.Undo();
   me = WindowsIdentity.GetCurrent().ToString();
}
[...]

Ho inserito anche la stringa me all’interno del codice in modo possiate vedere l’effettivo mantenimento della Identity via debug. Per maggiori info sulla Impersonate » e sui Thread »

p.s: I valori passati al Thred, molto femminili, servono solamente per intervenire sul mio personale stato di Stress, aumentando le quantità di testosterone circolanti. E in omaggio vi metto pure una foto della splendida Claudia Rossi :) Spero che gli amici programmatori puritani  e  omosessuali non me ne vogliano! Questo blog è cmq sempre crossover.

Ordinare i file di un DirectoryInfo per reverse date

February 14th, 2008 No comments

In asp.net è possibile ottenere tutti i file di una directory (oggetto DirectoryInfo) utilizzando il metodo GetFiles() che restituisce un array di oggetti FileInfo.

Se proviamo a fare l’output di questo array ci aggiorgiamo che non abbiamo modo di ordinarlo per data, e soprattutto per data inversa. Utilizziamo per farlo un oggetto SortedList e una piccola classe del tipo ICompare. L’oggetto SortedList permette di inserire una lista di elementi con chiave e valore (key, value).

Ecco il codice completo:

public class myReverserClass : IComparer<DateTime>
    {
        #region IComparer<DateTime> Members

        public int Compare(DateTime x, DateTime y)
        {
            return DateTime.Compare(y, x);
        }

        #endregion
    }

//recupero file creati
        FileInfo[] filesLast = rootTmpInfo.GetFiles();   

        //creo una sorted list e la popolo
        IComparer<DateTime> myComparer = new myReverserClass();
        SortedList<DateTime, FileInfo> filesLastSL = new SortedList<DateTime, FileInfo>(myComparer);
        foreach (FileInfo fi in filesLast)
        {
            filesLastSL.Add(fi.LastWriteTime, fi);
        }

        //colonne dati
        foreach (KeyValuePair<DateTime,FileInfo> fik in filesLastSL)
        {
            FileInfo fi = fik.Value;
        Response.write("chiave: " + fik.key + " Nome file: " + fi.Name);
        }

Cosa abbiamo fatto:

  1. abbiamo creato la SortedList, l’abbiamo popolata partendo dall’array
  2. abbiamo quindi creato un oggetto ICompare tipizzato DateTime (ICompare<DateTime>)
  3. abbiamo prodotto l’output dalla SortedList.

Grazie infinite a Davide per il supporto fisico / morale.

 

Categorie: Critiche Tag: ,