Inserito da: mandev | Novembre 9, 2008

USING AJAX and .NET with Ajax.dll

In the last years I used the integration between Server Code and Client Code with the aid of XMLHttp ActiveX.
From my ASPX or HTML page, with JavaScript, I created the XMLHttp object and, usually, I called an ASMX file. An example of this use is the bound of many dropdownlist without call a Post Back of the page. Another example is an asynchronous treeview. When you expand a node you can call a Web Service method that return, in his values, an XML that you can draw under the node father.
This method run correctly and I’ve many applications, today on line, that use it. But there are also some problems:  a difficult debug, with the integration between C# server code and JavaScript, and – in many case – a difficult maintenance of code.

Today we can do it with Ajax (Asynchronous JavaScript and Xml). There are many solutions to write the code: in the web you can find many JavaScript framework that run with JSon  or Xml.

Developing my project I not found, anyway, a solution that satisfied me.

Finally I found a solution that has a simple code to write and an easy debug: it’s also cross browser J

. With this solution, for example, I wrote some Server Custom Control that, after rendered a classical textbox,  in her  Onblur client event save in the C# Session the value of the field.

 

And now… some code please!!

You need download the Ajax.dll, wrote by M. Schwarz, HERE.

Then you can create a simple Web Application (in this example I use C#). 

 

After created the project you can put in the Project Reference the Ajax.dll.

And, finally, the last configuration step. In the <system.web> node of your web.config you need paste this code:

<system.web>

      <httpHandlers>

        <add verb=POST,GET path=ajax/*.ashx type=Ajax.PageHandlerFactory, Ajax />

      </httpHandlers>

OK!  Here we are, and we can start with real code.

In this example we will create two Ajax methods, a void and a function. 

The void is called setValue and memorizes in a session the value of a string, passed by the JavaScript code.
If you want “see” the method also in the JavaScript code you need describe the method like an Ajax method.  For to do it add this code before  your method:

[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]

In your static method you can use all the libraries and classes of the framework.

 

[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]

public static void setValue(string MyValue, string SessionName)

{

HttpContext.Current.Session[SessionName] = MyValue;

}

 

Now, we can write the method that read this session and for do it we need create a function.  We need add the type of the method like the void for tell to the system that this is an Ajax method.  Then, like a usual function, we read the Session and then, after tested it, we return the value.

[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]

public static string getValue(string SessionName)

{

if (HttpContext.Current.Session[SessionName] != null)

       {

       return HttpContext.Current.Session[SessionName].ToString();

       }

       else

       {

       return “No value for the request session”;

       }

           

}

Now, we can write the code in the aspx page. Before everything we need register type for Ajax and the code to do this is very very simple.
In the pageLoad of you page paste this code.

Ajax.Utility.RegisterTypeForAjax(typeof(Code.AjaxSample));

Where Code.AjaxSample is the type of your Class.

If, for example, you use a big application with many application layers, probably you’ll have a DLL for Business Logic, another with CustomControl ecc… With this method you can put your Ajax code in external dll without problem.

In the C# code we described the methods like Ajax method; so, now, you see them in you JavaScript Code.
Both the methods were STATIC method, so we don’t need create any object, but just invoke it.

 

<!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>Untitled Page</title>

    <script language=”javascript”>

    function setClientMethod()

    {

        var _strValue = document.getElementById(“string1″).value;

        var _strSessName = document.getElementById(“string2″).value;

        AjaxSample.setValue(_strValue, _strSessName);

        alert(“Session saved!!”);

    }

   

    function getClientMethod()

    { 

        var _strSessName = document.getElementById(“string2″).value;

        var _rslt = AjaxSample.getValue( _strSessName);

        if(_rslt != null)

        {

            document.getElementById(“RSLT”).innerHTML = _rslt.value;

        }

    }

   

    </script>

</head>

<body>

    <form id=”form1″ runat=”server”>

    <div>

    String Value<input type=”text” id=”string1″ /> – Session Name<input type=”text” id=”string2″ /> <input type=”button” onclick=”setClientMethod();” value=”GO!!!”/>

    <input type=”button” onclick=”getClientMethod();” value=”READ VALUES!!!”/>

    <br />

    Results: <div id=”RSLT” style=”float:left”></div>

   

    </div>

    </form>

</body>

</html>

 

In our page we have 2 textbox and a first button. The button GO!!! Call a JavaScript function that invoke the method of C# code. If you set a breakpoint in your C# code and you run the project you will see that, in the server side, you received the values of the client side!

With the READ VALUES button you call your server and you read the HttpContext Session Value. You can also, clearly, read a database, download data from a server etc…

With this method you can do many solutions for your projects. It’s very simple debug the code and also you can put the “important” code in a DLL and not in a JavaScript code.

 

You can download the article in Microsoft Word here: Using Ajax and .NET

You can also download the source project with example here

 

Ho installato sulla mia WMWare con 2k3 R2 la versione di WSS 3.0.

Tutto gira perfettamente: volevo però spostare i file fisici di DB (visto che SharePoint salva tutto su DB)  su un disco secondario con più spazio, così da non avere problemi futuri.
Tentando di fare questo mi sono accorto che i servizi Windows (tale è WSS) utilizzano un database di sistema che non è navigabile tramite il Management Studio.

Incuriosito dalla cosa ho fatto un po’ di ricerca trovando un po’ di post che fornivano trucchetti più o meno complicati per accedere e vedere il db.

Alla fine ho trovato questo articolo che mi ha fornito la soluzione. Per collegarsi a questo DB tramite Management Studio è necessario usare come server di registrazione la seguente stringa.

 \\.\pipe\mssql$microsoft##ssee\sql\query

in questo modo sono riuscito quindi a fare il Detach del database per poi spostare i file fisici sul nuovo disco.  

 

 

In un progetto che sto seguendo si ha la necessità di creare, in modo automatico,  all’interno di una Document Library dei link a dei documenti che appartengono ad un’altra Document Library.
I documenti da linkare vengono gestiti con un Workflow e solo al termine dello stesso si può creare la copia.

Dato che la pubblicazione non deve essere sincrona alla fine del Workflow e dato che volevo eseguire un po’ di test su dei servizi Windows ho creato un piccolo Windows Service che non fa altro che chiamare una libreria esterna che esegue una serie di operazioni che desidero compiere: creare link, gestire le cartelle ecc…

Nella mia situazione partivo da questi dati preliminari:

1)      La struttura tra le due Document Library è speculare: quindi stesse cartelle e stessi percorsi

2)      La Document Library in cui andavo a copiare i documenti era autorizzata a vedere tutti i documenti in questione. Non avevo quindi bisogno di pormi il problema della gestione dell’authority.

Detto questo: ho creato una libreria che espone un metodo statico

public static void LinkAllDocuments(string WebSite, string FromLibrary, string DestLibrary)

, metodo che richiamerà poi una funzione ricorsiva  (di tipo private), che scorrerà tutte gli item e le subfolder della list che stiamo analizzando

 

Il metodo pubblico accetta come parametri di input il WebSite dove si va ad operare e le due Document Library.
Questo metodo, volutamente, scorre brutalmente tutti i documenti della library.

Per poter creare un Item di tipo Content Type LINK è necessario inserire nella pagina ASPX che si va a creare del codice XSLT al fine di comunicare a MOSS che stiamo lavorando su un link.
Nel codice sottostante il percorso al documento che funge da template è in chiaro: è poi facilmente inseribile in una configurazione applicativa.

public static void LinkAllDocuments(string WebSite, string FromLibrary, string DestLibrary)

        {

           SPSite Site = new SPSite(WebSite);

           Web = Site.OpenWeb();

           oList = Web.Lists[FromLibrary];

           CreaLink(oList.RootFolder, DestLibrary);

        }

 

        private static void CreaLink(SPFolder folder, string DestLibrary)

        {

            try

            {

               

                foreach (SPFile file in folder.Files)

                {

                  //controllo che lo stato di un documento sia nello stato che desidero

                    if (file.Item["Stato"].ToString().ToUpper() == “PUBBLICATO”)

                    {

                            string _fldDest = file.ParentFolder.ToString();

                            SPFolder _c = Web.GetFolder(_fldDest);

                            if (_c.Exists)

                            {

                                //link al file

                                string fileLinkUrl = Web.Url + “/” + file.Url;

                                StringBuilder builder = new StringBuilder();

 

                                using (TextReader reader = new StreamReader(@”C:\linktodocumenttemplate.txt”))

                                {

                                    builder.Append(reader.ReadToEnd());

                                }

 

                                builder.Replace(“{0}”, fileLinkUrl);

 

                                SPFile _newFile = _c.Files.Add(file.Name + “.aspx”, UTF8Encoding.UTF8.GetBytes(builder.ToString()), true);

 

                                //impostiamo le proprietà del nuovo link

                                SPListItem item = _newFile.Item;

                                item["Content Type"] = “Link”;

                                SPFieldUrlValue itemUrl = new SPFieldUrlValue();

                                itemUrl.Description = file.Title;

                                itemUrl.Url = fileLinkUrl;

                                item["URL"] = itemUrl;

                                //eseguiamo la COMMIT dei dati inseriti

                                item.Update();

                            }

                       

                    }

                }

//scorriamo tutte le sotto cartelle della cartella attuale

                foreach (SPFolder subfolder in folder.SubFolders)

                {

 

                    CreaLink(subfolder, DestLibrary);

                }

            }

 

 

            catch (Exception e)

            {

 

                //Gestiamo l’errore           

     }

        }

 

 

 

Qui di seguito il contenuto del file TXT che usiamo come template:

<%@ Assembly Name=Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c %>

<%@ Register TagPrefix=SharePoint Namespace=Microsoft.SharePoint.WebControls Assembly=Microsoft.SharePoint %>

<%@ Import Namespace=System.IO %>

<%@ Import Namespace=Microsoft.SharePoint %>

<%@ Import Namespace=Microsoft.SharePoint.Utilities %>

<%@ Import Namespace=Microsoft.SharePoint.WebControls %>

 

<html xmlns:mso=urn:schemas-microsoft-com:office:office xmlns:msdt=uuid:C2F41010-65B3-11d1-A29F-00AA00C14882>

<Head> <META Name=progid Content=SharePoint.Link>

<!–[if gte mso 9]><xml>

<mso:CustomDocumentProperties>

<mso:URL msdt:dt=”string”>{0}, {0}</mso:URL>

<mso:ContentType msdt:dt=”string”>Link to a Document</mso:ContentType>

</mso:CustomDocumentProperties>

</xml><![endif]–>

</head>

    <body>

        <form id=Form1 runat=server>

            <SharePoint:UrlRedirector id=Redirector1 runat=server />

        </form>

    </body>

</html>

 

File Word con l’articolo: creare-un-link-automaticamente-tra-due-document-library-in-moss-2007

 

Inserito da: mandev | Settembre 30, 2008

Windows Vista + Windows Live Messenger

Con l’installazione di Windows Vista Business ho riscontrato un problema nella connessione a Live Messenger.
Anche a FireWall spento, porte aperte e quant’altro continuava a non farmi collegare, come se non avesse proprio connessione ad internet.
il problema si risolve eseguendo (come amministratore della macchina) questo comando a livello DOS.

netsh int tcp set global autotuninglevel

 

 

Inserito da: mandev | Settembre 22, 2008

Gestione FTP in C# con il FrameWork 2.0

Con l’avvento del FrameWork 2.0 si è andata ad aggiungere una classe molto utile per noi programmatori: la FtpWebRequest. In passato per interagire via FTP con dei server bisognava usare i socket e spesso la cosa non era scontata.
Con questa classe adesso è davvero molto semplice interagire via FTP con i server ed effettuare tutte le operazioni che vogliamo.
Oggi andiamo a creare una classe che si occuperà di uplodare un file, scaricarlo e poi cancellarlo.
Il .cs che trovato in allegato contiene due classi: la prima è la FtpState classe fornita direttamente dal SDK del Frame Work e poi la nostra vera e propria classe che compierà le operazioni desiderate. In questo caso l’abbiamo chiamata PepMindFtp.
Andiamo ad analizzare i tre metodi (i metodi sono tutti statici):

StartIt: in modo asincrono si occupa di uplodare un file sul server

/// <summary>
/// Metodo per l'upload di uno specifico file
/// </summary>
/// <param name="Url">ftp://www.miosito.it/fld/file.txt</param>
/// <param name="fileLocalName">nome del file locale che uplodiamo</param>
/// <param name="UserName">utente FTP</param>
/// <param name="Password">password FTP</param>

/// <summary>
/// Metodo per il download specifico di un file
/// </summary>
/// <param name=“Url”>indirizzo ftp correttamente impostato://www.miosito.it/fld/file.txt</param>
/// <param name=“UserName”>utente FTP</param>
/// <param name=“Password”>password FTP</param>
/// <returns>Ritorna uno stream di dati</returns>

DeleteFile: elimina un file specifico sul server

/// <summary>
/// Metodoper la cancellazione di un file
/// </summary>
/// <param name="Url">indirizzo ftp correttamente impostato://www.miosito.it/fld/file.txt</param>
/// <param name="UserName">utente FTP</param>
/// <param name="Password">password FTP</param>
/// <returns>Booleano con l'esito dell'operazione</returns>

Il primo metodo opera asincronicamente, ma va chiaramente implementata la parte applicativa che lo possa gestire. Vediamo un piccolo esempio:
In questa applicazione ho necessità di uplodare i file da un’applicazione Windows Form su un server remoto. Le soluzioni potevano essere due:
La prima era quella di storare dentro Sql Server lo stream dell’immagine. Questa soluzione si però poi rivelata poco performante. La seconda è quella di salvare su un server FTP la nostra immagine.Associamo ad un bottone il nostro evento.

private void button2_Click(object sender, EventArgs e){
 
  IAsyncResult ar = null;
 
  AsyncCallback __as = new AsyncCallback(allega);
 
  __as.BeginInvoke(ar, null, null);
 
}
 
private void allega(IAsyncResult ar){
 
  pictureBox11.Image= Image.FromFile(ConfigurationSettings.AppSettings["WAIT"]);
 
  //visualizziamo nella nostra picturebox un file di loading… 
  //estraiamo il nome del file dalla sua path completa
 
  string __fileName = this.txt_FileAttach.Text.Substring(this.txt_FileAttach.Text.LastIndexOf("\") +1);
 
  string __fileFtp =  "ftp://www.mioserver/miacartella/" + __fileName
 
  PepMindFtp.StartIt(__fileFtp, txt_FileAttach.Text, "myUser", "myPwd");
 
}

A questo punto possiamo facilmente visualizzare i file in modo asincrono oppure sincrono.
Il vantaggio è che l’upload dei file è gestito separatamente e quindi la vostra applicazione è libera di fare altre operazioni.
Lo stesso vale per gli altri due metodi.

Scarica il sorgente in PDF facendo click qui: pepmindftp

Inserito da: mandev | Gennaio 25, 2008

I Pilastri della Terra (Ken Follett)

I pilastri della terra I pilastri della Terra.

Esce nella prima edizione nel 1989. E’ il primo libro che ho letto di Follett e devo dire che è veramente splendido. E’ ambientato nel XII Secolo e racconta della realizzazione in teoria utopistica di una cattedrale. La vicenda dura una vita, e si muove trasversalmente tra i vari personaggi del libro: Tom il costruttore, Ellen la selvaggia, il priore Philip, il vescovo Bigod, William Hamleigh – signorotto locale crudele e senza scrupoli – .

La storia ha la potenza di far vivere e respirare quei giorni, la difficoltà di reperire i materiali, i contrasti politici e non solo tra le figure di riferimento dell’epoca (il priore, l’arcivescovo ecc…).

Pur essendo un tomo di 1000 e passa pagine il libro scorre benissimo, ed è uno di quei libri che quando lo finisci ti viene da dire “…no, è già finito…”.

Particolarmente studiata è la psicologia dei personaggi che non risulta mai banale e che non stanca.

Davvero un bel libro. Da non perdere.

Inserito da: mandev | Settembre 11, 2007

Creazione di un’interfaccia JS per i WebService

Nelle pagine web e negli applicativi web (sia intranet che internet) JS sta acquistando sempre un maggior ruolo. Uno degli utilizzi più interessanti di JS è quello di chiamare WebService (anche in modo asincrono) per recuperare dei dati senza utilizzare il classico PostBack o redirect  ad altra pagina. Ogni volta che in .NET creiamo un WS possiamo richiamarlo  in più modi: tramite codice .NET all’interno del CodeBehind, tramite http o tramite SOAP.
Quello che vogliamo utilizzare noi è il metodo tramite SOAP. Premetto che questa parte di codice funziona solo con IE dato che è stato utilizzato per una Web Application non multi-browser, ma è poi facilmente estendibile anche a FireFox, Mozzilla ecc…
Se si esegue nel browser il nostro ASMX vedremo che all’interno di ogni metodo sono presenti gli esempi di chiamata.
Di seguito quello che vogliamo utilizzare noi.

<?xml version=”1.0″ encoding=”utf-8″?>
<soap:Envelope xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”> 
<soap:Body>   
<getComuni xmlns=”http://www.sintax.org/WS”>
     
<Nazione>
int</Nazione>     
<Provincia>
string</Provincia>   
</getComuni> 
</soap:Body>
<soap:Evenlop>

 Il NameSpace del nostro WS  è www.sintax.org/WS. E’ descrittivo, non vincolante al funzionamento del WS, ma cmq opportuno metterlo con il dominio che ospita il nostro WS.
Il metodo che vogliamo chiamare è getComuni e i parametri che il WS richiede sono un intero ed una stringa.
Il nostro obiettivo è creare un oggetto parametrico che sia indipendente da quale WS venga chiamato, dal suo Namespace, dal nome del metodo e dai suoi parametri.
Dato che chiameremo il nostro WS in modo asincrono, vogliamo che quando abbia finito la sua chiamata richiami una nostra funzione esterna al WS che ne prenda il risultato e lo elabori.
       Pariamo con il codice:methodName à il nome del metodo
param
à nodi XML che contengono i parametri correttamente impostati
callBack
à funzione JS di ritorno da eseguire quando il WS ha finito
wsUrl
à l’url del WS del tipo (../WS/miows.asmx)
nameSpace
à il namespace del WS.
questi ultimi parametri in questo esempio sono “inchiavaradati” nel codice, ma niente vieta di metterli in variabili Globali della pagina.

var xmlVall = null;  
//DEVE ESSERE GLOBALE

function miniSoap(methodName, param, callBack, wsUrl, nameSpace){ 
      //qui controlliamo che il browser riesca ad instanziare l’oggeto XMLHTTP   
     if (window.XMLHttpRequest)
    
{
        
xmlVal=new XMLHttpRequest()      
     }
 
    
else if (window.ActiveXObject)
    
{
      
xmlVal=new ActiveXObject(“Microsoft.XMLHTTP”)
    
} 

 

     if (xmlVal!=null)
    
{          
     //apriamo il nostro oggetto dicendogli che passiamo in POST, gli diamo l’url e gli dicamo che deve essere asincrono   
          
      
xmlVal.open (“POST”, wsUrl, true);          
      
xmlVal.setRequestHeader( “Content-Type”,“text/xml; charset=utf-8″);
       //costruiamo la nostra SOAPAction
       xmlVal.setRequestHeader(“SOAPAction”, nameSpace + “/” + methodName);
          
      
var strRequest = “<?xml version=’1.0′ encoding=’utf-8′?>”;
          
      
strRequest += “<soap:Envelope xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’ xmlns:xsd=’http://www.w3.org/2001/XMLSchema’xmlns:soap=’http://schemas.xmlsoap.org/soap/envelope/’>”;
              strRequest += “<soap:Body>”;
           //metodo e namespace 
          
      
strRequest += “<”+ methodName +” xmlns=\”"+ nameSpace +“/\”>”;             
       //I parametri
       strRequest +=  param;      
       //chiusura del nodo del metodo
       strRequest += “</”+ methodName +“>”;
          
      
strRequest += “</soap:Body>”;          
      
strRequest += “</soap:Envelope>”;        

       //l’evento onreadystatechange è fondamentale per dirgli cosa fare al momento che
       la chiamata  restituisce un risultato
       xmlVal.onreadystatechange= eval(callBack);
       //il callBack è la nostra funziona(es:pippo())
          
      
xmlVal.send(strRequest);        
      
}
       else
       
{
         
alert(“il tuo browser non supporta XMLHttp”)        
       
}
} 

Vediamo adesso un esempio di chiamata al nostro miniSoap.
function  execWS(){
  var
strRequest = “<Nazione>1</ Nazione >”;          
  strRequest += “<Provincia>ROMA</Provincia>”;
  miniSoap(“getComuni”, strRequest, “callBackComuni”, “../WS/qualiproxy.asmx”, “http://sintax.org/WS”);  
}  
Qui di seguito la funzione callBack che viene eseguita al momento in cui il WS termina la sua esecuzione. Controlliamo che lo stato di ritorno sia 4 (esito corretto) e poi possiamo tranquillamente utilizzare l’xml di ritorno a piaciemento 

function  callBackComuni()
{
  
if (xmlVal.readyState==4)
  
{
     
var xmlDoc = new ActiveXObject(“Msxml2.DOMDocument”);
   
  xmlDoc.async = false; 
     
xmlDoc.resolveExternals = false;
 
     
xmlDoc.loadXML(xmlVal.responseXML.xml);
     
alert(xmlVal.responseXML.xml);
   
}
}—————-

 

 

 

File in versione DOC integrazione JS + WS

Può capitare, nel fare programmi, di ereditare basi dati già create e di cui non abbiamo né una specifica né un po’ di documentazione. E’ quello che mi è capitato in un recente sviluppo. Database con più di 50 tabelle, tutte collegate con molte (troppe) FK. Dovendo mettere mano ai dati, mi si è posta la necessità di eliminare automaticamente le FK dal database.

Ecco di seguito lo script, che chiaramente si appoggia ai Sysobject di SqlServer…

declare @cmd nvarchar(500)
declare @foreign_table nvarchar(500)
declare @foreign_key_name nvarchar(500)
DECLARE Kur CURSOR FOR
select cast(f.name as varchar(255)) as foreign_key_name,
cast(c.name as varchar(255)) as foreign_table
from sysobjects f inner join sysobjects c on f.parent_obj = c.id
inner join sysreferences r on f.id = r.constid inner join sysobjects p on r.rkeyid = p.id
inner join syscolumns rc on r.rkeyid = rc.id and r.rkey1 = rc.colid
inner join syscolumns fc on r.fkeyid = fc.id and r.fkey1 = fc.colid
left join syscolumns rc2 on r.rkeyid = rc2.id and r.rkey2 = rc.colid
left join syscolumns fc2 on r.fkeyid = fc2.id and r.fkey2 = fc.colid
where f.type = ‘F’
OPEN Kur
FETCH NEXT FROM Kur
into @foreign_key_name, @foreign_table
WHILE @@FETCH_STATUS = 0
BEGIN
set @cmd=’ ALTER TABLE ‘ + @foreign_table + ‘ DROP CONSTRAINT ‘ + @foreign_key_name
/*print @cmd prima di eseguire magari diamo un occhio alle query che vengono generate*/
exec sp_executesql @cmd
FETCH NEXT FROM Kur
into @foreign_key_name, @foreign_table
END
CLOSE Kur

Inserito da: mandev | Settembre 5, 2007

Opening Blog

Ciao! Apro questo blog non perchè abbia un motivo per aprirlo, ma perché non ho un motivo per non farlo. Per di più è gratis. Quindi…

Categorie