SlideShare una empresa de Scribd logo
1 de 45
Descargar para leer sin conexión
DIPARTIMENTO DI INGEGNERIA

CORSO DI LAUREA TRIENNALE IN INGEGNERIA DELL'INFORMAZIONE

                     CURRICULUM INFORMATICA




 Porting evolutivo di una applicazione per la gestione di dati
         di riferimenti biliografici in ambiente .NET 4.5




Relatore : Prof. Maurizio Fermeglia

Laureando : Giulio Ambrogi

Anno Accademico : 2011 / 2012
Indice dei contenuti

CAPITOLO 1 Introduzione (pag. 3)

CAPITOLO 2 Analisi dei requisiti e della situazione esistente

       2.1 Intervista al committente (pag. 5)

       2.2 Analisi della situazione esistente (pag. 6)

              2.2.1 Il database (pag. 6)

              2.2.2 Applicazione esistente (pag. 9)

              2.2.3 Data Bindig (pag 12)

              2.2.4 SharePoint e Web Application (pag. 12)

CAPITOLO 3 Progettazione

       3.1 Principi generali di progettazione (pag. 13)

CAPITOLO 4 Implementazione

       4.1 Upload di file (pag. 15)

       4.2 Cancellazione di file (pag. 22)

       4.3 Opzioni utente (pag. 25)

       4.4 Export (pag. 26)

       4.5 Implementazioni di carattere generale (pag. 41)

CAPITOLO 5 Conclusioni

       5.1 Possibili miglioramenti futuri (pag. 43)

       5.2 Conclusioni (pag. 43)


                                             2
CAPITOLO 1

Introduzione

L'obiettivo di questa tesi è estendere le funzionalità di un'applicazione client
esistente la quale è utilizzata per la gestione dei riferimenti bibliografici e delle

attività del laboratorio MOSE.
In particolare si vuole fornire all'utente, che utilizzerà l'applicazione,la possibilità di

gestire l'upload e la cancellazione di documenti relativi alle pubblicazione, di
         'upload      cancellazione

esportare in forma tabellare un insieme di record bibliografici e si intende
migliorare ulteriormente l'interfaccia utente ,per rendere l'applicazione
maggiormente user friendly , coerentemente con le nuove funzionalità da

implementare.



Nei capitoli successivi le singole funzionalità e la loro implementazione verranno

illustrate nello specifico.

La situazione iniziale vede l'esistenza di :

- versione beta dell'applicazione di cui si vuole effettuare il porting, ancora priva

delle sopracitate funzionalità;

- una base di dati ,su server remoto , nella quale sono immagazzinate tutte le
informazioni utilizzate dall'applicazione, come dati anagrafici, dati bibliografici,

ecc. ;

- un'istanza di SharePoint Server installata su un server remoto (un altro), utilizzata
dalla web application che lavora in parallelo all'applicazione in questione; è da

notare che quest'ultima ancora non comunica con tale istanza ;




                                               3
in questo server vengono salvati i file pdf relativi alle pubblicazioni ;

- una web application che presenta sul Web i dati bibliografici e permette
all'utente di effettuare il download di un file pdf relativo ad una pubblicazione




Ciò che ha motivato la realizzazione di questo lavoro è la necessità di permettere
all'utente di svolgere alcune operazioni direttamente dall'applicazione, ovvero

svincolare l'utente dall'utilizzo di ulteriori software , garantendo così una maggiore
semplicità di esecuzione, una presentazione dei dati funzionale ed una maggiore

sicurezza relativamente all'integrità dei dati e all'aggiornamento degli stessi.

I vincoli progettuali sono rappresentati in primo luogo dallo sviluppo in ambiente
.NET, utilizzando la tecnologia Windows Presentation Foundation e il linguaggio

di programmazione C#, in secondo luogo ,relativamente all'applicazione già
esistente, dall'attenersi per quanto possibile alla sua logica e infine

dall'implementare il tutto in modo tale che possa essere accessibile alla web
application.

Gli obiettivi di questo lavoro sono :

- analisi dei requisiti da parte del committente;

- analisi della situazione preesistente;

- studio delle tecnologie .NET, e nel particolare di WPF e C#;

- studio del funzionamento delle interazioni tra Database, applicazione e server;

- progettazione del front-end;

- realizzazione effettiva e compilazione su piattaforma .NET Framework 4.5;

- test e distribuzione dell'applicazione.


                                            4
CAPITOLO 2

Analisi dei requisiti e della situazione esistente
                                         esistente



2.1 Intervista al committente



Le richieste del committente per la nuova

versione dell'applicazione sono :

    •   effettuare un analisi degli oggetti
         ffettuare
        programmabili (viste , stored
                       viste

        procedures , user defined functions
                                  functions)
        effettivamente utilizzati

        dall'applicazione al fine di effettuare un lavoro di pulizia nella base di dati
                                                                                   dati;

    •   effettuare l'upload di un documento relativo ad una determinata
         ffettuare

        pubblicazione nel server sul quale è presente un'istanza di ShareP
                                                                    SharePoint

        Server , aggiornando allo stesso tempo i valori presenti nella base di dati
        (Titolo del pdf e ID del documento)
                                 documento).

        Questo documento dovrà poi essere reperibile dalla web application che
        permette la visualizzazione dei contenuti dal web
                                                      web;

    •   effettuare la cancellazione di un documento (analogamente all'upload
         ffettuare
        bisogna gestire entrambi i "lati" : SharePoint e SQL Server) ed avere a

        disposizione opportuni controlli per verificare la presenza o meno di un




                                              5
documento, e potere gestire facilmente le azioni (upload , cancellazione,
        presentazione) relative ad esso;

    •   poter esportare un file in formato Excel nel quale vengano riportati tutti i

        dati relativi al titolo della pubblicazione, all'anno , agli autori, alla
        denominazione e ai riferimenti, fornendo inoltre all'utente la possibilità di

        filtrare i risultati a suo piacimento prima di effettuare l'export;

    •   eventuali accorgimenti per migliorare ulteriormente il front end.




2.2 Analisi della situazione esistente

2.2.1 Il database
2.2.1

La base di dati esistente è sita in un server remoto ( di3.units.it ) ed è composta da
27 tabelle, 63 viste e 133 stored procedures.

Contiene tutti i dati inerenti la gestione del laboratorio come, ad esempio: dati

anagrafici dei dipendenti, dati delle pubblicazioni, congressi, progetti e tesi.

Le viste utilizzate dall'applicazione esistente sono:

   •    ViewPubblicazioniRivista : mette in relazione le informazioni delle riviste con

        le informazioni dello staff;
   •    ViewPubblicazioniCongressi : mette in relazione i le informazioni dello staff

        con il congresso relativo alla pubblicazione ;
   •    Staff_View : una raccolta dei dati anagrafici dei membri dello staff .

   •    ViewPubblicazioniRivista_Staff: variante della prima vista citata

Le stored procedures utilizzate dall'applicazione esistente sono:




                                             6
•   sp_PubbStaff : utilizzata per visualizzare le pubblicazioni relative ad un
       membro dello staff. Riceve in input 2 parametri: @ID_staff è l'ID del

       componente dello staff, mentre @ID_output è un parametro che se settato
       a 0 fornisce sia le pubblicazioni presentate in un congresso che in una

       rivista, se settato ad 1 fornisce solo le pubblicazioni presentate in un
       congresso ed infine se settato a 2 fornisce solo le pubblicazioni presentate

       in una rivista
   •   sp_PubbWeb: utilizzata per visualizzare le pubblicazioni presentate nel sito

       web del MOSE. Riceve in input un parametro @ID_SitoWeb , che
       rappresenta l'identificatore del sito web.



Non sono state trovate invece User Defined Functions.

Nella Figura 1 si riporta il Database Diagram della base di dati in questione :




                                          7
TBL_Options                      tblRiviste                                tblAnno                                 TBL_PDFDocument                                Versions
            ID                          ID_rivista                                  ID_Anno                              IDTitolo
                                                                                                                                                                        VersionId

            FolderPDFDocument           Denominazione                               Anno                                 NameFile
                                                                                                                                                                        Version

                                        RivistaInternazionale
                                                                                                                                                                        Id

                                        Referee
                                                                                                                                                                        UserName

                                        [Luogo pubblicazione]
                                                                                                                                                                        TimeStamp

                                        ISSN
                                                                                                                                                                        FinalizeTimeStamp

                                                                                                                                                                        Mode

                                                                                                                                                                        ModeStack

                                                                                                                                                                        Updates

                                                                                                                                                                        Notes
     tblProgetti                                                tblTesiDettaglio                                      tblTesi
             ID_Progetto
                                                                   ID_Tesi
                                                                                                                          ID_Tesi
             Progetto
                                                                   DettaglioIT
                                                                                                                          ID_Tipo
             SiglaProgetto
                                                                   DettaglioEN                                            ArgomentoIT
             Anno_Inizio
                                                                                                                          ArgomentoEN                                  tblTesiStato
             Anno_Fine                                                                                                                                                       ID_Stato
                                                                                                                          Collaborazione
             Finanziatore                                                                                                                                                    StatoTesi
                                                                                                                          Correlatori
             ResponsabileLocale
                                                                                                                          ID_Curriculum
             ResponsabileGlobale                                tblCurriculum
                                                                                                                          Stato
             FinanziamentoLocale                                   ID_Curriculum
                                                                                                                          ID_Relatore
             FinanziamentoGlobale                                  Curriculum
                                                                                                                          Autore
             VIsualizzaSito                                        CurriculumEN                                                                                        tblTipiTesi
                                                                                                                          DataInizioTesi
                                                                                                                                                                             ID_Tipo
             TipoProgetto
                                                                                                                          MEseLAurea
                                                                                                                                                                             Tipo
             imgproject
                                                                                                                          AnnoLaurea
             summary
                                                                                                                          Voto
             link


                                                                tblStaffCongressi
                                                                                                                      tblStaff
                                                                   ID_Staff                                                                                            tblStaffGruppi
                                                                                                                          ID_Staff
                                                                   ID_Congresso                                                                                              ID_Gruppo
                                                                                                                          Cognome
                                                                   Presentazione                                                                                             ID_Staff
                                                                                                                          Nome
                                                                   Organizzazione                                                                                            Amministratore
                                                                                                                          Attivo
   tblTItoloProgetto                                               Partecipazione
                                                                                                                          Username
         ID_progetto
                                                                   SuInvito
                                                                                                                          Amministratore
         ID_titolo
                                                                                                                          PhotoFileName

                                                                                                                          PhoneNumber

                                                                                                                          OfficeLocation

                                                                                                                          Email                                        tblGruppi
                                                                tblCongressi                                              Summary                                            ID_Gruppo
                                                                   ID_Congresso
                                                                                                                          Education                                          Nome
 tblKeyword                                                        Denominazione
                                                                                                                          ResearchActivity                                   Note
     ID_Keyword
                                                                   Data
                                                                                                                          ResearchProject
     Keyword
                                                                   Anno
                                                                                                                          Collaborations
                                                                   CongressoIntenazionale
                                                                                                                          Enabled
                                                                   Referee




tblCollegamentoKeywordsTitolo                                                                                                                tblStaffCorsi
   Id_Keyword                          tblTitoli                                                                                                  ID_Staff
                                                                                              tblStaffTitoli
                                               ID_Titolo                                                                                          ID_Corso
   ID_Titolo                                                                                      ID_Staff
                                               Autori                                                                                             Organizzatore
                                                                                                  ID_Titoli
                                               Riferimento

                                               ID_Stato

                                               ID_Rivista

                                               ID_Congresso                                                                                  tblCorsi
                                               Anno
                                                                                              tblTipoPubbl                                       ID_Corso

                                                                                                  ID_TipoPubb                                    NomeCorso
                                               Titolo
tblStatoTitolo                                                                                    TipoPubblicazione                              EnteOrganizzatore
    ID_Stato                                   ID_tipoPubb
                                                                                                  TipoPubEnglish                                 Periodo
    Stato                                      ID_SitoW eb
                                                                                                  Class_TS                                       Luogo
    Statoen                                    ImpactFactor
                                                                                                  Class_PD                                       Anno
                                               ID_Settore




                                                                                                                                                                         Figura 1
                                                                                              8
2.2.2
2.2.2 Analisi dell'applicazione esistente

Questa applicazione è stata implementata utilizzando la tecnologia Windows

Presentation Foundation (linguaggi C# e XAML).

Il suo aspetto richiama quello delle applicazioni della suite Microsoft Office 2010.

Alcuni studi sulla User Experience condotti dalle più importanti software house,

                                                                         hanno
                                                                         dimostrato

                                                                         come ,
                                                                         attraverso
                                                                         l'uso di
                                                                         tecniche come

                                                                         l'eye tracking,
                                                                         l'utente tenda
 Figura 2
                                                                         a leggere i
contenuti delle pagine focalizzando maggiormente la propria attenzione su due

linee orizzontali nella parte alta della pagina e su una linea verticale nella parte
sinistra della pagina, secondo quello che è noto come schema ad F. Questo

rappresenta un grande punto di forza per l'applicazione.

La pagina visualizzata in Figura 2 è la home dell'applicazione , nella quale sono
presenti link testuali che rimandano alle diverse pagine, e pulsanti (nella banda in

grigio chiaro) che rimandano alle stesse.

L'applicazione esistente è di tipo navigation-based nello stile di numerose altre
                                   navigation-based,
applicazioni come Windows Explorer e Windows Media Player.

Le pagine sulle quali è stata focalizzata maggiormente l'attenzione sono quelle

relative alla gestione e alla presentazione dei dati relativi alle pubblicazioni
                                                                   pubblicazioni.



                                            9
Figura 3

Nella pagina relativa alle pubblicazioni si nota la presenza di 3 pulsanti: Dettaglio ,

Griglia e Staff Il primo di questi , lo si può già vedere nell'immagine, fornisce i
          Staff.
dettagli della pubblicazione selezionata attraverso gli appositi controlli (Figura 3), il

secondo fornisce una vista in un formato griglia, simulando l'interfaccia di una
tabella di SQL Server (Figura 4) ed il terzo infine raggruppa, in formato-griglia, le

pubblicazioni in base all'autore (Figura 5) ,che può essere selezionato attraverso
una apposita listbox.




  Figura 4




                                           10
I pulsanti Export e Upload non svolgono ancora alcuna funzione.




Figura 5




2.2.3 Data Binding

Lo scambio di dati tra applicazione e database avviene grazie ad una stringa di
connessione denominata MoseDBConnectionString.

Il tipo di autenticazione utilizzata è Windows Authentication.

<add name="MoseUXPrototype.Properties.Settings.MoseDBConnectionString"
             connectionString="Data Source=SERVERNAMESQLEXPRESS;
            Initial Catalog=MoseDB;Integrated Security=True"
             providerName="System.Data.SqlClient" />



Invece le interazioni tra applicazione e SharePoint (su server remoto) saranno
implementate come richieste HTTP corredate delle opportune credenziali e

verranno illustrate in seguito.




                                         11
Questa stringa si trova nel file ./MoseUXPrototype.exe.config.xaml , il quale è
presente nel folder della versione distribuibile dell'applicazione.



2.2.4 Sharepoint Server e Web Application
È presente inoltre una applicazione web che presenta le informazioni

bibliografiche su un sito web. Questo sito web è stato creato utilizzando Microsoft
SharePoint.

SharePoint è un software lato server che permette la creazione di particolari siti
web attraverso lo strumento software SharePoint Designer, con il quale è possibile

gestire, tra le varie cose, un archivio di file che possono essere utilizzati
dall'applicazione web.

I file delle pubblicazioni infatti sono salvati in una apposita cartella (
www.mose.units.it/doc ).




                                            12
CAPITOLO 3

Progettazione



3.1 Principi generali di progettazione



L'idea di fondo è sempre quella di conservare il layout dell'applicazione esistente,
per quanto possibile, mantenendo vivace l'interfaccia e garantendone un facile e
sicuro utilizzo da parte dell'utente.

Per quanto riguarda sia l'upload che l'export si è deciso di implementare queste

due funzionalità su due diverse finestre e non delle pagine : il motivo principale è
                                finestre,
il voler marcare la differenza sostanziale tra la gestione di file e la gestione di

record.

Si immagini di suddividere le funzionalità dell'applicazione su due livelli differenti:

    •     lettura/scrittura di record (comunicazioni tra applicazione e base di dati)

    •     gestione di file (upload / cancellazione) ed export (comunicazioni tra
          applicazione , SharePoint e base di dati )

L'intera applicazione esistente si presenta all'utente su un'unica finestra e l'utente

può accedere ai diversi contenuti sfogliando tra le pagine di essa.
Si è preferito invece implementare le nuove funzionalità per la gestione dei file , su

finestre pop up , in modo tale da dare all'utente la sensazione di utilizzare uno
strumento con vero e proprio. Si intende implementare quindi un Uploader ed un

Exporter.



                                            13
Si intende inoltre permettere all'utente di gestire le connessioni e le credenziali per
le interazioni web con i server, quindi sarà implementata un ulteriore finestra pop

up per la consolle delle opzioni.

Queste finestre saranno aperte da opportuni pulsanti posizionati nelle pagine
dell'applicazione coerentemente con la loro funzione.




                                          14
CAPITOLO 4

Implementazione



4.1 Upload



Si vuole caricare un file , relativo ad una determinata pubblicazione, su SharePoint

ed aggiornare i record del database SQL Server che associano "id della
                                                              id
pubblicazione" con "titolo del pdf (Figura 6).
                    titolo     pdf"




                                                                        Figura 6


Il pulsante che permette di accedere a questa funzionalità è il pulsante Upload che
è implementato nella pagina Pubblicazioni (Figura 3,4,5).

Cliccando su tale pulsante si accede ad un nuova finestra : la console di upload
                                        una

(Figura 7).

L'interfaccia (figura 7) di questa finestra è stata implementata in modo tale da :
  interfaccia


                                         15
•   selezionare, attraverso una listBox, la pubblicazione per la quale si vuole
       effettuare l'upload del file;

   •   cercare e selezionare il file da caricare;

   •   selezionare il server e il percorso all'interno del quale caricare il
       documento;

   •    di impostare le proprie credenziali (Username, Dominio e Password);

   •   eseguire effettivamente l'upload.

È presente inoltre un pulsante per effettuare un refresh della finestra.




                                                                               Figura 7




                                           16
La listbox che presenta le pubblicazioni esistenti viene popolata attraverso il
metodo RiempiListbox(), il quale esegue una query di tipo select sul database

descritto dalla stringa di connessione, si riporta di seguito il codice:



public void RiempiListBox()
{
try
{
string query = "select ID_Titolo, Anno, Titolo
                    from ViewPubblicazioniCongressi union
                    select     ID_Titolo,Anno,Titolo
                    from ViewPubblicazioniRivista";
SqlConnection cn=new
SqlConnection(Properties.Settings.Default.MoseDBConnectionString);
SqlCommand cm = new SqlCommand(query);
cm.Connection = cn;
cn.Open();
SqlDataReader dr = cm.ExecuteReader();
while (dr.Read())
      {
          listBox1.Items.Add(dr["ID_Titolo"]+", "+dr["Anno"]+", "+dr["Titolo"]);
      }
 dr.Close();
 dr.Dispose();
}
catch (SqlException ex)
               {
                    MessageBox.Show(ex.Message);
                }
}




Il file dialog per la selezione del documento da caricare viene invece aperto
cliccando sul pulsante Sfoglia (btnSfoglia) , si riporta di seguito il codice relativo:


private void btnSfoglia_Click(object sender, RoutedEventArgs e)




                                            17
{
       Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
       Microsoft.Win32.OpenFil
       Nullable<bool> result = dlg.ShowDialog();
                    >
       if (result == true
                     true)
               {
               string filename = dlg.FileName;
               // aggiorno il contenuto della textbox
               textBox1.Text = filename;
               }
           }



Una tipica esecuzione dell'upload è rappresentata in pseudo codice in Figura 8 :
                                    rappresentata




  Figura 8




Di seguito è riportato il codice dell'effettivo upload del documento:

private bool Upload(string myFile)
                    string
       {
       try



                                           18
{
      //UPLOAD SU SQL SERVER
      SqlConnection connection1 = new
      SqlConnection(Properties.Settings.Default.MoseDBConnectionString);
      string id = listBox1.SelectedItem.ToString();
      string[] words = id.Split(',');
      //creo un array contenente i campi della selezione
      SqlCommand command = new SqlCommand("select IDTitolo from TBL_PDFDocument
                                                     where IDTitolo=" + words[0]);
      command.Connection = connection1;
      connection1.Open(); //apro la connessione
      if (command.ExecuteScalar() != null){
                  connection1.Close();
                  }
      else { //se non c'è il documento nel db lo inserisco


                      connection1.Close();
                      SqlCommand insertPdf = new SqlCommand("insert into
                      TBL_PDFDocument values ("
                      + words[0] + " , " + "'P" + returnID() + ".pdf')");
                      insertPdf.Connection = connection1;
                      connection1.Open();
                      insertPdf.ExecuteNonQuery();
                      connection1.Close();
                  }
      connection1.Close();
    //UPLOAD SU SHAREPOINT
      WebClient client = new WebClient();
      //vado a reperire le credenziali dell'utente
      client.Credentials = new System.Net.NetworkCredential(textBox4.Text,
                                             passwordBox1.Password, textBox5.Text);
      string url="http://"+textBox2.Text+":" + textBox3.Text+"/";
      client.UploadFile(url+"P"+returnID()+".pdf" , "PUT", myFile);
      client.Dispose();
      MessageBox.Show("upload su sharepoint e su sql eseguito
                           nDocumento : p"+returnID()+".pdf");
}
catch (Exception err)
      {
          MessageBox.Show(err.Message);



                                             19
return false;
          }
          return true;
 }

Analisi del codice [ metodo Upload ]
Come si puo' notare il metodo è diviso fondamentalmente in due parti
                                                               parti:

l'aggiornamento di record su SQL Server e l'upload su SharePoint.
Per quanto riguarda l'aggiornamento del record su SQL Server , le fasi di
realizzazione sono:
     •   creazione di un nuovo oggetto Connection (per poter comunicare con

         l'istanza di SQL Server) e in particolare attraverso l'utilizzo della
         MoseDBConnectionString.

     •   reperimento dell'ID del documento selezionato dalla listbox , attraverso un
         metodo abbastanza rudimentale ma efficace: ovvero, viene effettuato un

         parsing dell'elemento selezionato (in formato stringa) al fine di estrarre il
         primo membro separato da virgola, ovvero l'ID della pubblicazione

     •   costruzione della query in linguaggio Transact-SQL
         Questa query fornisce un risultato numerico, se il documento è già

         presente nella tabella (tabella delle pubblicazioni aventi già un file relativo
         caricato), altrimenti restituisce un valore nullo se questo file non è presente:

              •   Se il record è già presente nella tabella, questo record non viene
                  aggiornato;

              •   Se il record non è presente viene eseguita una nuova query
                  (statement di tipo INSERT ) che inserisce nella tabella (ID, nome del

                  file).
E' da notare che il nome del file , obbedisce ad uno standard dovuto ad un vincolo

imposto dalla web application ,che lavora in parallelo con questa applicazione , in
particolare il nome del file dovrà essere nel formato "Pxxxx.pdf" dove xxxx




                                             20
rappresenta l'id della pubblicazione (ad es. se l'id della pubblicazione è 16 , il
documento si chiamerà "p0016.pdf").


Il metodo returnID() è un semplice metodo che utilizza l'ID della pubblicazione

selezionata e crea la parte numerica del nome del file apponendo a sinistra dell'ID
tanti zeri quanti sono necessari al fine di ottenere un nome con 4 cifre .


private string returnID()
        {
             string id = listBox1.SelectedItem.ToString();
             string[] words = id.Split(',');
             string returnstring;
             if (words[0].Length == 1) {
                      returnstring = "000" + words[0];
                      return returnstring; }
             else if (words[0].Length == 2) {
                      returnstring = "00" + words[0];
                      return returnstring; }
             else if (words[0].Length == 3) {
                      returnstring = "0" + words[0]; return returnstring; }
             else {
                      return words[0]; }
        }



Per quanto riguarda l'upload del documento su SharePoint
                      upload                  SharePoint:

   •   in input si riceve il path del file (locale) da caricare;
   •   viene creato un oggetto di tipo client che sarà il virtuale esecutore

       dell'upload;
   •   a questo oggetto vengono assegnate le credenziali per la richiesta http ,

       che saranno reperite dalle textBox (Username e Dominio) e dalla
       passwordBox (Password);

   •   viene costruita la stringa dell'url nel quale sarà caricato il file andando a
       reperire le informazioni dalle textBox (Server e Folder);



                                            21
•   attraverso il metodo UploadFile dell'oggetto di tipo WebClient viene poi
         ttraverso
        caricato il documento su SharePoint , per mezzo di una richiesta HTTP di

        tipo PUT.

4.2 Cancellazione di files




 Figura 9

E' stata implementata un interfaccia utente per migliorare l'interazione con le

funzionalità aggiunte e per dare all'utente la possibilità di cancellare un file pdf
                                                                                 pdf.
Nella schermata relativa al dettaglio della pubblicazione (Figura 9 ) sono stati

aggiunti :
    •   un indicatore che segnala se è presente o meno, nel database ,un file

        relativo alla pubblicazione selezionata
                                    selezionata;
    •   un pulsante che rimanda alla finestra di upload;

    •   un pulsante che permette, in caso di presenza di un file, di cancellarlo.
                                             presenza


È più interessante concentrarsi sull'implementazione di quest'ultimo considerata la
semplicità degli altri controlli citati.

Come per l'upload del documento, la cancellazione dovrà essere effettuata su
                                                               effettuata
entrambi i "lati" (SQL Server e SharePoint)
                   SQL          SharePoint).




                                           22
Per il primo contesto viene eseguita una query del tipo : "delete   from

TBL_PDFDocument where IDTitolo= ".

Mentre per la cancellazione in ambiente SharePoint viene eseguita una richiesta

http di tipo DELETE, corredando la request delle credenziali opportune.
Si riporta di seguito il codice utilizzato per la cancellazione del documento.




Figura 10

  private void DeletePDF()
                {
                      try
                      {
                    //CANCELLAZIONE SU SQL SERVER
                      System.Windows.Window loading =
                    new System.Windows.Window { Height = 100, Width = 200,
                      WindowStartupLocation = WindowStartupLocation.CenterScreen,
                      WindowStyle = WindowStyle.None };
                      loading.Content = new TextBlock { Text = "Please Wait",
                      FontSize = 30, FontWeight = FontWeights.Bold,
                      HorizontalAlignment = HorizontalAlignment.Center,
                      VerticalAlignment = VerticalAlignment.Center };
                      loading.Show();// Mostra finestra di attesa
                      tblTitoli currentTitle =
                      (tblTitoli)this.MasterView.CurrentItem;




                                         23
int IDTitolo = currentTitle.ID_Titolo;
                     SqlConnection connection1 =
                 new
SqlConnection(Properties.Settings.Default.MoseDBConnectionString);
                     SqlCommand command =
                 new SqlCommand("delete from TBL_PDFDocument
                                    where IDTitolo=" + IDTitolo);
                 command.Connection = connection1;
                 connection1.Open();
                 command.ExecuteNonQuery();
                 connection1.Close();
                 label1.Content= SetLabel();
                 //CANCELLAZIONE SU SHAREPOINT
                 string nomeFile = "P" + returnID() + ".pdf";
                 string url = "http://"+Properties.Settings.Default.Server+":"
                                    +Properties.Settings.Default.Sito
                                    +"/"+nomeFile; //server:sito
                 HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
                req.Credentials =
      new System.Net.NetworkCredential(Properties.Settings.Default.Username,
                 Properties.Settings.Default.Password,
                 Properties.Settings.Default.Dominio);
                 req.Method="DELETE";
                 HttpWebResponse response = (HttpWebResponse)req.GetResponse();
                 loading.Close();
                 MessageBox.Show("Il documento : P" + returnID()
                                    + ".pdf è stato eliminato");
                 }
                     catch (Exception e)
                     {
                         MessageBox.Show(e.Message);
                     }
}




                                           24
4.3 Opzioni Utente




 Figura 11



Il pulsante Opzioni (Figura 11) permette all'utente di visualizzare una nuova finestra

(Figura 12) all'interno della quale sarà possibile impostare dei valori di default per
le credenziali, in modo tale da non dover selezionare il server ed autenticarsi ogni

qualvolta si dovesse caricare o cancellare un documento da SharePoint.
Queste impostazioni di configurazione, sono salvate, al primo utilizzo

dell'applicazione, nel file MoseUXPrototype,xml.config , mentre successivamente in
automatico, l'applicazione andrà a reperire questi settaggi da un file presente in

C:/Users/NomeUser/AppData/Local/ che viene creato al primo utilizzo di questa .
All'interno di questa finestra, il pulsante Conferma esegue una modifica del valore

delle stringhe di default presenti nelle file di configurazione dell'applicazione:
   •   Properties.Settings.Default.Server,
   •   Properties.Settings.Default.Sito,
   •   Properties.Settings.Default.Username,
   •   Properties.Settings.Default.Password,
   •   Properties.Settings.Default.Dominio.




                                          25
Figura 12




4.4 Export
Questa funzione permette all'utente di esportare in un foglio elettronico Excel i
dati delle pubblicazioni.

In particolare le informazioni che possono essere reperite sono:
   •   Anno di pubblicazione;

   •   Titolo ;
   •   Autore/i ;

   •   Riferimento ;
   •   Congresso (nel quale è stata presentata la pubblicazione) .

Sono presenti inoltre alcuni filtri aggiuntivi che permettono di raffinare la ricerca:
   •   intervallo di tempo (anni);

   •   tipo di pubblicazione;
   •   membro dello staff (autore).


Come si può notare nell'immagine (Figura 13), l'utente può scegliere se inserire o

meno ognuno dei 5 campi in alto a sinistra , selezionando o deselezionando le
checkbox.




                                          26
Il processo di esportazione
in formato Excel dei dati

richiesti dall'utente si
svolge in 4 passaggi

fondamentali:
    1. operazioni

        preliminari (ad es.
        popolamento

        combobox)
    2. costruzione della

        query da eseguire
        sulla base di dati, in

        base ai campi
        selezionati

        dall'utente
    3. compilazione di un                                                         Figura 13

        file di testo semplice , utilizzando il delimitatore tab (t), utilizzando i dati di
        output della query

    4. apertura del file di testo da parte dell'applicazione Excel riconoscendo il tab



Primo passo


La comboBox relativa ai membri dello staff si popola grazie ad una query eseguita
sulla base di dati, questa query estrapola Nome e Cognome dei membri dello staff


public void LoadCmbStaff()
       {
       try
       {



                                             27
SqlConnection cn = new
       SqlConnection(Properties.Settings.Default.MoseDBConnectionString);
       SqlCommand cm = new SqlCommand("SELECT Cognome , Nome      FROM tblStaff");
       cm.Connection = cn;
       cn.Open();
       SqlDataReader dr = cm.ExecuteReader();
       while (dr.Read())
                 {
                      //popolamento della combobox
                      cmbStaff.Items.Add(dr["Cognome"]+" , "+dr["Nome"]);
                 }
                 dr.Close();
                 dr.Dispose();


             }
             catch (SqlException ex)
             {
                 MessageBox.Show(ex.Message);
             }
        }



Secondo passo
L'idea che sta alla base di questa implementazione è quella di analizzare elemento
per elemento (Titolo, Autore, Anno, ecc ) le richieste dell'utente e costruire
coerentemente la query.
L'algoritmo per la costruzione della stringa , che sarà il contenuto della query si

costituisce di 3 steps fondamentali, in base ai campi che vengono selezionati e in
base ai filtri che vengono attivati:

   •   costruzione della stringa "SELECT …FROM…"
   •   costruzione della stringa "WHERE …"

   •   coordinamento del tutto e costruzione della stringa completa




                                          28
Nelle pagine seguenti viene riportato l'algoritmo in pseudocodice (Figure 14 e
15):


           Stringa = «SELECT»                       Stringa1 = «WHERE»


                                                                                     F
                                      F
            Anno is checked                             IF Dal != null

                    T                                     T
                                                    Stringa1 = Stringa1 +
       Stringa = Stringa + «Anno»
                                                      «ANNO >= Dal »


                                      F                                              F
            Titolo is checked                            IF Al != null

                    T                                     T
                                                    Stringa1 = Stringa1 +
       Stringa = Stringa + «Titolo»
                                                       «ANNO <= Al »


                                      F                                              F
            Autori is checked                         IF Autore != Tutti

                    T                                     T
                                                   Stringa1 = Stringa1 +
   Stringa = Stringa + «Autori»
                                               «AUTORI LIKE ‘CognomeAutore’»


                                      F
        Riferimento is checked
                                                    strWhere =14
                                                       Figura Stringa1
                T

Stringa = Stringa + «Riferimento»


                                      F
       Denominazione is checked

                 T
           Stringa = Stringa +
           «Denominazione»




           strSelect = Stringa
                                                                         Figura 14




                                          29
X = tipoPubblicazione


                             T
           X==1
                                              Query = strSelect + «FROM dbo.ViewPubblicazioniCongressi» +strWhere

           F
                             T
           X==2                                 Query = strSelect + «FROM dbo.ViewPubblicazioniRiviste» +strWhere


       F
                             T                 Query = strSelect + «FROM dbo.ViewPubblicazioniCongressi» +strWhere
           X==0
                                              + «UNION» + strSelect + «FROM dbo.ViewPubblicazioniRiviste» +strWhere

           F

                                                                                                        Figura 15


Il passaggio finale (Figura 15) è motivato dal fatto che è possibile che una

pubblicazione sia riferita contemporaneamente ad una rivista e ad un congresso e
                                                                     congresso,
quindi bisogna fornire all'utente la possibilità di scegliere che tipo di dato

visualizzare , se la prima, se la seconda o se entrambe.
Di seguito si riporta il metodo per la creazione della parte iniziale della query:


string CorpoStringCongressi = " FROM                        dbo.ViewPubblicazioniCongressi ";
string CorpoStringRiviste = " FROM dbo.ViewPubblicazioniRivista ";


private string CostruisciQueryIniziale()
               {
                   string SelectBase = "SELECT ";
                   string Supporto = SelectBase;
                   if (checkBoxAnno.IsChecked == true)
                         {
                                 /*
                                     Questi IF interni servono ad evitare il caso in cui ci si
                                     trovi ad avere una
                                     Select del tipo: >> SELECT , NOME << (virgola in mezzo)
                                     */
                                 if (Supporto == "SELECT ") { Supporto = Supporto + " Anno ";}
                                 else
                                 {
                                          Supporto = Supporto + ", Anno ";



                                                              30
}
        }
    if (checkBoxTitolo.IsChecked == true)
    {
        if (Supporto == "SELECT ") { Supporto = Supporto + " Titolo "; }
        else
        {
            Supporto = Supporto + ", Titolo ";
        }
    }
    if (checkBoxAutori.IsChecked == true)
    {
        if (Supporto == "SELECT ") { Supporto = Supporto + " Autori "; }
        else
        {
            Supporto = Supporto + ", Autori ";
        }
    }


    if (checkBoxRiferimento.IsChecked == true)
    {
        if (Supporto == "SELECT "){ Supporto = Supporto+" Riferimento"; }
        else
        {
            Supporto = Supporto + ", Riferimento ";
        }
    }


    if (checkBoxCongresso.IsChecked == true)
    {
        if (Supporto == "SELECT "){ Supporto =Supporto+" Denominazione";}
        else
        {
            Supporto = Supporto + ", Denominazione ";
        }
    }
    return Supporto;
}




                               31
Di seguito si riporta il codice relativo allo statement WHERE della query:


private string CostruisciQueryWhere()
        {
            string Original = " WHERE ";
            string Supporto = Original;


            if (cmbStaff.Text != null && checkBoxStaff.IsChecked==false )
            {
                //nella combobox sono presenti COGNOME,NOME io vado ad utilizzare
                solo
                //il cognome facendo un parsing della stringa cmbbox.text
                string autore =cmbStaff.Text.ToString();
                string[] arr = autore.Split(',');
                if (Supporto == Original) //per risolvere il problema di "WHERE ,
                                               //NOME STAFF.." SINTASSI T-SQL
                {
                       Supporto = Supporto + " Autori LIKE '%" + arr[0] + "%' ";


                }
                else
                {
                       Supporto = Supporto + " AND " + " Autori LIKE '%"
                                    + arr[0] + "%' ";
                }
            }
            if ( textBoxDal.Text!=null && textBoxDal.Text!=""){
             if (Supporto == Original)
                {
                       Supporto = Supporto + " Anno >= "+ textBoxDal.Text + " ";
                }
                else
                {
                       Supporto = Supporto + " AND " + " Anno >= "
                       + textBoxDal.Text + " ";
                }
            }
            if (textBoxAl.Text != null && textBoxAl.Text != "")
            {




                                          32
if (Supporto == Original)
                   {
                       Supporto = Supporto + " Anno <= " + textBoxAl.Text + " ";
                   }
                   else
                   {
                       Supporto = Supporto + " AND " + " Anno <= "
                                      + textBoxAl.Text + " ";
                   }
            }


            //passaggio finale
            if (Supporto == Original)
            {
                   return "";
            }
            else
            {
                   return Supporto;
            }
        }



Infine si riporta il codice relativo alla concatenazione delle diverse sottostringhe e

alla formazione query completa:


private string CostruisciQuery()
        {
            string vuota = "";
            string TotalQuery = vuota;


            if (cmbTipoPubb.SelectedIndex == 0)
            {
                   TotalQuery = TotalQuery + CostruisciQueryIniziale() + " " +
                CorpoStringCongressi + CostruisciQueryWhere() + " UNION " +
                CostruisciQueryIniziale() + CorpoStringRiviste +
                CostruisciQueryWhere();
            }
            else if (cmbTipoPubb.SelectedIndex == 1)




                                           33
{
                     TotalQuery = TotalQuery + CostruisciQueryIniziale() +
                         CorpoStringCongressi + CostruisciQueryWhere();
              }
              else if (cmbTipoPubb.SelectedIndex == 2)
              {
                     TotalQuery = TotalQuery + CostruisciQueryIniziale() +
                         CorpoStringRiviste + CostruisciQueryWhere();
              }
              else
              {
                     TotalQuery = TotalQuery + CostruisciQueryIniziale() +
                  CorpoStringCongressi + CostruisciQueryWhere() + " UNION " +
                  CostruisciQueryIniziale() + CorpoStringRiviste +
                  CostruisciQueryWhere();
              }
              Console.WriteLine(TotalQuery);
              if (TotalQuery != vuota)
              {
                     return TotalQuery;
              }
              else return vuota;
        }




Terzo passo


Di seguito si riporta il codice per la costruzione del file di testo:


public string generaCsv(int colonne, string sqlCommand)
        {
        string csvFile = ".//TempFile.txt";
        try
        {
       string connectionString =
       Properties.Settings.Default.MoseDBConnectionString;
       using (SqlConnection connection = new        SqlConnection(connectionString))
                     {



                                            34
try
                   {
                           connection.Open();
                       }
                       catch (System.Data.SqlClient.SqlException ex)
                       {
                       // handle
                       return "";
                       }
        using (SqlDataAdapter adapter =
        new SqlDataAdapter(sqlCommand, connection))
               {
              using (System.Data.DataTable table =
        new System.Data.DataTable("tbl"))
                             {
                             adapter.Fill(table);
                             StringBuilder commaDelimitedText = new StringBuilder();
                             foreach (DataRow row in table.Rows)
                             {
                                 for (int i = 0; i < colonne; i++)
                                        {
/*Qui era sorto un problema, il mio "Generatore di Csv" , quando trovava 2 spazi
consecutivi                                                      li considerava come una nuova
colonna. risolto usando espressione regolare */
                                 row[i] = Regex.Replace(row[i].ToString(), @"s+", " ");
                                    }
                                            switch (colonne)
                                            {
                                                case 1:
                                                      {
                                                      string value = string.Format("{0}",
                                                          row[0]);
                                                      commaDelimitedText.AppendLine(value);


                            File.WriteAllText(csvFile,commaDelimitedText.ToString());
                                                      break;
                                                          }
                                                case 2:
                                                          {




                                                      35
string value=string.Format("{0}t{1}",
                         row[0], row[1]);
                          commaDelimitedText.AppendLine(value);


    File.WriteAllText(csvFile,commaDelimitedText.ToString());
                          break;
                              }
                    case 3:
                              {
                          string value =
                     string.Format("{0}t{1}t{2}", row[0], row[1],
                         row[2]);
                          commaDelimitedText.AppendLine(value);


    File.WriteAllText(csvFile,commaDelimitedText.ToString());
                          break;
                          }
                    case 4:
                          {
                          string value =
    string.Format("{0}t{1}t{2}t{3}",row[0], row[1], row[2],
                         row[3]);
                          commaDelimitedText.AppendLine(value);
        File.WriteAllText(csvFile,commaDelimitedText.ToString());
                          break;
                          }
                    case 5:
                          {
                          string value =
                         string.Format("{0}t{1}t{2}t{3}t{4}",
                         row[0], row[1], row[2], row[3], row[4]);
                          commaDelimitedText.AppendLine(value);
        File.WriteAllText(csvFile,commaDelimitedText.ToString());
                          break;
                              }
                }
            }
        }
    }
}



                          36
}


             catch (Exception ex)
             {
                   System.Windows.MessageBox.Show(ex.Message);
             }
             return csvFile;
        }

Analisi del codice
Questo metodo sfrutta il metodo Contacolonne() che restituisce il numero di colonne
che andranno a formare la tabella in formato Excel, il risultato di questo metodo è

passato come input (int        colonne).

È necessario contare le colonne perché la sintassi del comando string.Format(..)

permette di stabilire un unico tipo di formattazione.
L'input string   sqlCommand   è invece la query che sarà eseguita sulla base di dati.

Sono stati identificati 5 casi possibili in base al risultato del metodo Contacolonne().
Il riempimento del file di testo è effettuato attraverso un ciclo , all'interno del

quale vengono copiati nel file i dati della tabella (risultato della query) apponendo
un delimitatore /t eccezion fatta per l'ultima colonna ( /n).
                /t,

Questo file viene salvato con il nome TempFile.txt nella cartella in cui è presente
l'eseguibile dell'applicazione, ed ogni qual volta verrà eseguita un'operazione di

questo tipo lo stesso file verrà riscritto prevenendo problemi di capienza di
memoria o di semplice esubero di file non necessari.



Quarto passo


Una volta creato il file di testo viene aperto un foglio elettronico Excel il quale
attraverso l'impostazione che prevede il riconoscimento del delimitatore tab ( "/t" )
popola le sue celle in base a quanto contenuto nel file di testo.




                                               37
Successivamente verranno inserite le intestazioni delle colonne attraverso il
metodo generaIntestazioniExcel().

Il metodo CSVtoExcel prende in input:
    •   il path del file che si vuole aprire;

    •    il foglio Excel nel quale aprire il file;
    •    le coordinate della cella da cui iniziare la popolazione delle celle;

    •    un array di tipi di dato per le rispettive colonne;
    •   un valore booleano che che imposta l'autodimensionamento (o meno)

        delle colonne.
Di seguito si riporta il codice del metodo in questione:
public void CSVtoExcel(string importFileName, Excel.Worksheet destinationSheet,
        Excel.Range destinationRange, int[] columnDataTypes, bool autoFitColumns)
         {


             destinationSheet.QueryTables.Add( "TEXT;" +
             System.IO.Path.GetFullPath(importFileName),destinationRange,
             Type.Missing);
             destinationSheet.QueryTables[1].Name =
             System.IO.Path.GetFileNameWithoutExtension(importFileName);
             destinationSheet.QueryTables[1].FieldNames = true;
             destinationSheet.QueryTables[1].RowNumbers = false;
             destinationSheet.QueryTables[1].FillAdjacentFormulas = false;
             destinationSheet.QueryTables[1].PreserveFormatting = true;
             destinationSheet.QueryTables[1].RefreshOnFileOpen = false;
             destinationSheet.QueryTables[1].RefreshStyle =
             XlCellInsertionMode.xlInsertDeleteCells;
             destinationSheet.QueryTables[1].SavePassword = false;
             destinationSheet.QueryTables[1].SaveData = true;
             destinationSheet.QueryTables[1].AdjustColumnWidth = true;
             destinationSheet.QueryTables[1].RefreshPeriod = 0;
             destinationSheet.QueryTables[1].TextFilePromptOnRefresh = false;
             //l'id 65001 rappresenta l'id della piattaforma che decodifica i
             contenuti in UTF-8
             destinationSheet.QueryTables[1].TextFilePlatform = 65001;
             destinationSheet.QueryTables[1].TextFileStartRow = 1;




                                              38
destinationSheet.QueryTables[1].TextFileParseType =
             XlTextParsingType.xlDelimited;
             destinationSheet.QueryTables[1].TextFileTextQualifier =
             XlTextQualifier.xlTextQualifierDoubleQuote;
             destinationSheet.QueryTables[1].TextFileConsecutiveDelimiter = false;
             destinationSheet.QueryTables[1].TextFileTabDelimiter = true;
             destinationSheet.QueryTables[1].TextFileSemicolonDelimiter = false;
             destinationSheet.QueryTables[1].TextFileCommaDelimiter = false;
             destinationSheet.QueryTables[1].TextFileSpaceDelimiter = false;
             destinationSheet.QueryTables[1].TextFileColumnDataTypes =
             columnDataTypes;
             destinationSheet.QueryTables[1].Refresh(false);




             if (autoFitColumns == true) {


       destinationSheet.QueryTables[1].Destination.EntireColumn.AutoFit();
                                             }


         }



Mentre il pulsante che aziona questo meccanismo agisce in questo modo: viene

aperta inizialmente una finestra che avvisa l'utente di attendere l'esecuzione del
processo, viene aperto un foglio Excel (non visibile ancora all'utente), viene

generato il file di testo sopra citato, viene eseguito il metodo CsvToExcel ,
vengono generate le intestazioni per le colonne del file Excel , dunque sparisce la

finestra di attesa e viene visualizzato il file.


private void button1_Click(object sender, RoutedEventArgs e)
         {
             try
             {
                   System.Windows.Window loading = new System.Windows.Window {
Height = 100,
                 Width = 200, WindowStartupLocation =
                 WindowStartupLocation.CenterScreen,
                 WindowStyle = WindowStyle.None };



                                             39
loading.Content = new TextBlock { Text = "Please Wait",
         FontSize = 30,FontWeight = FontWeights.Bold,
         HorizontalAlignment = HorizontalAlignment.Center,
         VerticalAlignment = VerticalAlignment.Center };
      loading.Show();


      Excel.Application xla = new Excel.Application();
      Excel.Workbook wb =
         xla.Workbooks.Add(Excel.XlSheetType.xlWorksheet);
      Excel.Worksheet ws = (Excel.Worksheet)xla.ActiveSheet;
      xla.Visible = false;
      int cln = contacolonne();
      string filepath = generaCsv(cln, CostruisciQuery());


      CSVtoExcel(filepath, (Excel.Worksheet)(wb.Worksheets[1]),


(Excel.Range)(((Excel.Worksheet)wb.Worksheets[1]).get_Range("$A$2")),
         new int[] { 2, 2, 2, 2, 2 }, true);
         //Come ultima cosa inserisco le intestazioni delle colonne
         List<string> lista = generaIntestazioniExcel();
         for (int i = 0; i < cln; i++)
           {
               ws.Cells[1, i + 1] = lista[i];
           }
           xla.Visible = true;
           wb.ActiveSheet.QueryTables[1].Delete();
           loading.Close();
     }
     catch (Exception myex)
     {
           MessageBox.Show(myex.Message);
     }
 }




                                  40
Il risultato di un possibile Export può essere:
(a) Creazione del file txt, non visibile all'utente




(b) Apertura del file da parte di Excel




4.5 Implementazioni di carattere generale
Sempre nell'ottica di migliorare ulteriormente l'interfaccia utente per renderla più

funzionali ai bisogni del committente sono implementate alcune features , di
minor rilevanza per, ma di indubbia utilità per l'utente:

   •   nella pagina relativa alle pubblicazioni in formato-griglia, viene aggiunta
       una colonna che presenta il nome del documento pdf , se presente, o nulla

       in caso contrario (Figura 16);
   •   per le pagine "PubblicationGrid" e "PubblicationCustom" è stato riscritto , in

       modo coerente con le modifiche apportate, il codice che permette
       all'utente di accedere ai dettagli della pubblicazione selezionata cliccando

       due volte sulla riga della griglia;
   •   sono stati abilitati, nella home page, i link testuali che rimandano alle

       pagine relative (come Upload e Export) e sono stati modificati i label relativi
       alla versione ed al nome dell'applicazione.




                                             41
Figura 16




            42
CAPITOLO 5


Conclusioni


5.1 Possibili miglioramenti
Svolgendo questo lavoro si è pensato inoltre a possibili miglioramenti , che

potrebbero essere sviluppati in futuro.
Tra i quali quelli di maggior rilevanza sono:

   •   funzionalità di import: permettere all'utente di effettuare un importazione
       di dati, da tabella excel, in modo tale da non dover inserire i record

       manualmente (ad esempio : nome, cognome e dati anagrafici di un nuovo
       membro dello staff).

       Questa feature alleggerirebbe ancor di più il lavoro per l'utente che
       attualmente deve inserire i nuovi dati , pur sempre via applicazione, ma

       manualmente
   •   versione web dell'applicazione, completamente svincolata quindi dal Pc

       dell'utente .
       Possibile utilizzo della tecnologia ASP.NET

5.2 Conclusioni
Features implementate
       Upload PDF

       Cancella PDF
       Export

       Gestione Credenziali



                                          43
L'obiettivo di implementare tutte le funzionalità richieste dal committente è stato
raggiunto.

Per quanto riguarda invece le conoscenze e le abilità acquisite, sono stati raggiunti
i seguenti obiettivi:

   •   raccolta dei requisiti mediante intervista al committente
   •   analisi della situazione esistente

   •   studio di .NET e di Windows Presentation Foundation
   •   studio di Database Relazionali

   •   studi sulle comunicazioni tra le diverse entità (server, applicazione, db)


L'applicazione ora non è più in fase di test (beta), ma è a tutti gli effetti in uso ,
nella sua versione 2.0
                   2.0.


Righe di codice scritte :

   •   C# : 700
   •   XAML : 300




                                            44
Bibliografia
  •   http://msdn.microsoft.com/en-us/library/aa970268.aspx (Introduction to
      WPF - MSDN)

  •   M. Miotto, "Progettazione e sviluppo di una applicazione per la gestione di

      dati bibliografici in ambiente .NET " , Tesi per corso di laurea triennale in

      Ingegneria Informatica (Università degli studi di Trieste)
  • Dispense del corso di Basi di Dati tenuto dal Dott. Fermeglia presso

      l'Università degli Studi di Trieste
  • http://msdn.microsoft.com/it-it/library/ms254978(v=vs.110).aspx

  • http://stackoverflow.com/questions/8947410/using-settings-settings-in-a-
      windows-wpf-app-vs2010

  • http://www.codeproject.com/Articles/19509/Write-Data-to-Excel-using-C
  • Adam Nathan - WPF 4 Unleashed - Pearson Education (US) – 2010
  • http://blogs.msdn.com/b/pietrobr/archive/2007/09/07/parliamo-di-linq-
      parte-3.aspx

  • http://msdn.microsoft.com/it-it/vcsharp/cc788743(en-us).aspx




                                            45

Más contenido relacionado

Similar a Porting evolutivo di una applicazione per la gestione di riferimenti bibliografici in ambiente .net 4.5

Progetto e implementazione di un processo per l'assemblaggio di documenti htm...
Progetto e implementazione di un processo per l'assemblaggio di documenti htm...Progetto e implementazione di un processo per l'assemblaggio di documenti htm...
Progetto e implementazione di un processo per l'assemblaggio di documenti htm...Nicola Furlan
 
Analisi delle dipendenze architetturali dei servizi di autenticazione SPID
Analisi delle dipendenze architetturali dei servizi di autenticazione SPIDAnalisi delle dipendenze architetturali dei servizi di autenticazione SPID
Analisi delle dipendenze architetturali dei servizi di autenticazione SPIDLeonardoSimonini
 
Master Informatica del Testo – Edizione elettronica - Arezzo - 2012
Master Informatica del Testo – Edizione elettronica - Arezzo - 2012Master Informatica del Testo – Edizione elettronica - Arezzo - 2012
Master Informatica del Testo – Edizione elettronica - Arezzo - 2012Walter Volpi
 
Progetto SOD Davide Sito
Progetto SOD Davide SitoProgetto SOD Davide Sito
Progetto SOD Davide SitoDavide Sito
 
SVILUPPO DI UNA APPLICAZIONE PER L’ACQUISIZIONE DI DATI DA SUPPORTO CARTACEO:...
SVILUPPO DI UNA APPLICAZIONE PER L’ACQUISIZIONE DI DATI DA SUPPORTO CARTACEO:...SVILUPPO DI UNA APPLICAZIONE PER L’ACQUISIZIONE DI DATI DA SUPPORTO CARTACEO:...
SVILUPPO DI UNA APPLICAZIONE PER L’ACQUISIZIONE DI DATI DA SUPPORTO CARTACEO:...guest12aaa586
 
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...daniel_zotti
 
Progetto e realizzazione di un'applicazione WebGIS per la visualizzazione di ...
Progetto e realizzazione di un'applicazione WebGIS per la visualizzazione di ...Progetto e realizzazione di un'applicazione WebGIS per la visualizzazione di ...
Progetto e realizzazione di un'applicazione WebGIS per la visualizzazione di ...diegohusu
 
eZ magazine: soluzione completa per la gestione multicanale della tua rivista
eZ magazine: soluzione completa per la gestione multicanale della tua rivistaeZ magazine: soluzione completa per la gestione multicanale della tua rivista
eZ magazine: soluzione completa per la gestione multicanale della tua rivistaGabriele Francescotto
 
Generazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptxGenerazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptxGiacomoZorzin
 
Realizzazione di una base di dati per la gestione delle valutazioni di proget...
Realizzazione di una base di dati per la gestione delle valutazioni di proget...Realizzazione di una base di dati per la gestione delle valutazioni di proget...
Realizzazione di una base di dati per la gestione delle valutazioni di proget...Efrem Venturuzzo
 
Installazione del cms alfresco
Installazione del cms alfrescoInstallazione del cms alfresco
Installazione del cms alfrescoMirco Leo
 
Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...
Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...
Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...artemedea
 

Similar a Porting evolutivo di una applicazione per la gestione di riferimenti bibliografici in ambiente .net 4.5 (20)

Progetto e implementazione di un processo per l'assemblaggio di documenti htm...
Progetto e implementazione di un processo per l'assemblaggio di documenti htm...Progetto e implementazione di un processo per l'assemblaggio di documenti htm...
Progetto e implementazione di un processo per l'assemblaggio di documenti htm...
 
Analisi delle dipendenze architetturali dei servizi di autenticazione SPID
Analisi delle dipendenze architetturali dei servizi di autenticazione SPIDAnalisi delle dipendenze architetturali dei servizi di autenticazione SPID
Analisi delle dipendenze architetturali dei servizi di autenticazione SPID
 
Master Informatica del Testo – Edizione elettronica - Arezzo - 2012
Master Informatica del Testo – Edizione elettronica - Arezzo - 2012Master Informatica del Testo – Edizione elettronica - Arezzo - 2012
Master Informatica del Testo – Edizione elettronica - Arezzo - 2012
 
Relazione Agic
Relazione AgicRelazione Agic
Relazione Agic
 
Progetto SOD Davide Sito
Progetto SOD Davide SitoProgetto SOD Davide Sito
Progetto SOD Davide Sito
 
DDive - 8.5.2 Xpages - L'evoluzione continua
DDive - 8.5.2 Xpages - L'evoluzione continuaDDive - 8.5.2 Xpages - L'evoluzione continua
DDive - 8.5.2 Xpages - L'evoluzione continua
 
SVILUPPO DI UNA APPLICAZIONE PER L’ACQUISIZIONE DI DATI DA SUPPORTO CARTACEO:...
SVILUPPO DI UNA APPLICAZIONE PER L’ACQUISIZIONE DI DATI DA SUPPORTO CARTACEO:...SVILUPPO DI UNA APPLICAZIONE PER L’ACQUISIZIONE DI DATI DA SUPPORTO CARTACEO:...
SVILUPPO DI UNA APPLICAZIONE PER L’ACQUISIZIONE DI DATI DA SUPPORTO CARTACEO:...
 
ORM Java - Hibernate
ORM Java - HibernateORM Java - Hibernate
ORM Java - Hibernate
 
Slide Soru - Collana Seminari CRS4 2015
Slide Soru - Collana Seminari CRS4 2015Slide Soru - Collana Seminari CRS4 2015
Slide Soru - Collana Seminari CRS4 2015
 
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
Progettazione e sviluppo di un'applicazione web per la gestione di dati di at...
 
DDive11 - xpages
DDive11 - xpagesDDive11 - xpages
DDive11 - xpages
 
Progetto e realizzazione di un'applicazione WebGIS per la visualizzazione di ...
Progetto e realizzazione di un'applicazione WebGIS per la visualizzazione di ...Progetto e realizzazione di un'applicazione WebGIS per la visualizzazione di ...
Progetto e realizzazione di un'applicazione WebGIS per la visualizzazione di ...
 
eZ magazine: soluzione completa per la gestione multicanale della tua rivista
eZ magazine: soluzione completa per la gestione multicanale della tua rivistaeZ magazine: soluzione completa per la gestione multicanale della tua rivista
eZ magazine: soluzione completa per la gestione multicanale della tua rivista
 
Generazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptxGenerazione automatica diagrammi di rete con template pptx
Generazione automatica diagrammi di rete con template pptx
 
Realizzazione di una base di dati per la gestione delle valutazioni di proget...
Realizzazione di una base di dati per la gestione delle valutazioni di proget...Realizzazione di una base di dati per la gestione delle valutazioni di proget...
Realizzazione di una base di dati per la gestione delle valutazioni di proget...
 
Data flow
Data flowData flow
Data flow
 
Ddive Xpage852
Ddive Xpage852Ddive Xpage852
Ddive Xpage852
 
Xpages, cosa ci sarà in questa nuova tecnologia
Xpages, cosa ci sarà in questa nuova tecnologiaXpages, cosa ci sarà in questa nuova tecnologia
Xpages, cosa ci sarà in questa nuova tecnologia
 
Installazione del cms alfresco
Installazione del cms alfrescoInstallazione del cms alfresco
Installazione del cms alfresco
 
Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...
Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...
Studio e realizzazione di un sw per la gestione dei profili e delle versioni ...
 

Último

IL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla Cresima
IL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla CresimaIL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla Cresima
IL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla CresimaRafael Figueredo
 
lezione di fisica_I moti nel piano_Amaldi
lezione di fisica_I moti nel piano_Amaldilezione di fisica_I moti nel piano_Amaldi
lezione di fisica_I moti nel piano_Amaldivaleriodinoia35
 
XI Lezione - Arabo LAR Giath Rammo @ Libera Accademia Romana
XI Lezione - Arabo LAR Giath Rammo @ Libera Accademia RomanaXI Lezione - Arabo LAR Giath Rammo @ Libera Accademia Romana
XI Lezione - Arabo LAR Giath Rammo @ Libera Accademia RomanaStefano Lariccia
 
XIII Lezione - Arabo G.Rammo @ Libera Accademia Romana
XIII Lezione - Arabo G.Rammo @ Libera Accademia RomanaXIII Lezione - Arabo G.Rammo @ Libera Accademia Romana
XIII Lezione - Arabo G.Rammo @ Libera Accademia RomanaStefano Lariccia
 
La seconda guerra mondiale per licei e scuole medie
La seconda guerra mondiale per licei e scuole medieLa seconda guerra mondiale per licei e scuole medie
La seconda guerra mondiale per licei e scuole medieVincenzoPantalena1
 
Corso di digitalizzazione e reti per segretario amministrativo
Corso di digitalizzazione e reti per segretario amministrativoCorso di digitalizzazione e reti per segretario amministrativo
Corso di digitalizzazione e reti per segretario amministrativovaleriodinoia35
 
Esperimenti_laboratorio di fisica per la scuola superiore
Esperimenti_laboratorio di fisica per la scuola superioreEsperimenti_laboratorio di fisica per la scuola superiore
Esperimenti_laboratorio di fisica per la scuola superiorevaleriodinoia35
 
Ticonzero news 148.pdf aprile 2024 Terza cultura
Ticonzero news 148.pdf aprile 2024 Terza culturaTiconzero news 148.pdf aprile 2024 Terza cultura
Ticonzero news 148.pdf aprile 2024 Terza culturaPierLuigi Albini
 

Último (8)

IL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla Cresima
IL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla CresimaIL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla Cresima
IL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla Cresima
 
lezione di fisica_I moti nel piano_Amaldi
lezione di fisica_I moti nel piano_Amaldilezione di fisica_I moti nel piano_Amaldi
lezione di fisica_I moti nel piano_Amaldi
 
XI Lezione - Arabo LAR Giath Rammo @ Libera Accademia Romana
XI Lezione - Arabo LAR Giath Rammo @ Libera Accademia RomanaXI Lezione - Arabo LAR Giath Rammo @ Libera Accademia Romana
XI Lezione - Arabo LAR Giath Rammo @ Libera Accademia Romana
 
XIII Lezione - Arabo G.Rammo @ Libera Accademia Romana
XIII Lezione - Arabo G.Rammo @ Libera Accademia RomanaXIII Lezione - Arabo G.Rammo @ Libera Accademia Romana
XIII Lezione - Arabo G.Rammo @ Libera Accademia Romana
 
La seconda guerra mondiale per licei e scuole medie
La seconda guerra mondiale per licei e scuole medieLa seconda guerra mondiale per licei e scuole medie
La seconda guerra mondiale per licei e scuole medie
 
Corso di digitalizzazione e reti per segretario amministrativo
Corso di digitalizzazione e reti per segretario amministrativoCorso di digitalizzazione e reti per segretario amministrativo
Corso di digitalizzazione e reti per segretario amministrativo
 
Esperimenti_laboratorio di fisica per la scuola superiore
Esperimenti_laboratorio di fisica per la scuola superioreEsperimenti_laboratorio di fisica per la scuola superiore
Esperimenti_laboratorio di fisica per la scuola superiore
 
Ticonzero news 148.pdf aprile 2024 Terza cultura
Ticonzero news 148.pdf aprile 2024 Terza culturaTiconzero news 148.pdf aprile 2024 Terza cultura
Ticonzero news 148.pdf aprile 2024 Terza cultura
 

Porting evolutivo di una applicazione per la gestione di riferimenti bibliografici in ambiente .net 4.5

  • 1. DIPARTIMENTO DI INGEGNERIA CORSO DI LAUREA TRIENNALE IN INGEGNERIA DELL'INFORMAZIONE CURRICULUM INFORMATICA Porting evolutivo di una applicazione per la gestione di dati di riferimenti biliografici in ambiente .NET 4.5 Relatore : Prof. Maurizio Fermeglia Laureando : Giulio Ambrogi Anno Accademico : 2011 / 2012
  • 2. Indice dei contenuti CAPITOLO 1 Introduzione (pag. 3) CAPITOLO 2 Analisi dei requisiti e della situazione esistente 2.1 Intervista al committente (pag. 5) 2.2 Analisi della situazione esistente (pag. 6) 2.2.1 Il database (pag. 6) 2.2.2 Applicazione esistente (pag. 9) 2.2.3 Data Bindig (pag 12) 2.2.4 SharePoint e Web Application (pag. 12) CAPITOLO 3 Progettazione 3.1 Principi generali di progettazione (pag. 13) CAPITOLO 4 Implementazione 4.1 Upload di file (pag. 15) 4.2 Cancellazione di file (pag. 22) 4.3 Opzioni utente (pag. 25) 4.4 Export (pag. 26) 4.5 Implementazioni di carattere generale (pag. 41) CAPITOLO 5 Conclusioni 5.1 Possibili miglioramenti futuri (pag. 43) 5.2 Conclusioni (pag. 43) 2
  • 3. CAPITOLO 1 Introduzione L'obiettivo di questa tesi è estendere le funzionalità di un'applicazione client esistente la quale è utilizzata per la gestione dei riferimenti bibliografici e delle attività del laboratorio MOSE. In particolare si vuole fornire all'utente, che utilizzerà l'applicazione,la possibilità di gestire l'upload e la cancellazione di documenti relativi alle pubblicazione, di 'upload cancellazione esportare in forma tabellare un insieme di record bibliografici e si intende migliorare ulteriormente l'interfaccia utente ,per rendere l'applicazione maggiormente user friendly , coerentemente con le nuove funzionalità da implementare. Nei capitoli successivi le singole funzionalità e la loro implementazione verranno illustrate nello specifico. La situazione iniziale vede l'esistenza di : - versione beta dell'applicazione di cui si vuole effettuare il porting, ancora priva delle sopracitate funzionalità; - una base di dati ,su server remoto , nella quale sono immagazzinate tutte le informazioni utilizzate dall'applicazione, come dati anagrafici, dati bibliografici, ecc. ; - un'istanza di SharePoint Server installata su un server remoto (un altro), utilizzata dalla web application che lavora in parallelo all'applicazione in questione; è da notare che quest'ultima ancora non comunica con tale istanza ; 3
  • 4. in questo server vengono salvati i file pdf relativi alle pubblicazioni ; - una web application che presenta sul Web i dati bibliografici e permette all'utente di effettuare il download di un file pdf relativo ad una pubblicazione Ciò che ha motivato la realizzazione di questo lavoro è la necessità di permettere all'utente di svolgere alcune operazioni direttamente dall'applicazione, ovvero svincolare l'utente dall'utilizzo di ulteriori software , garantendo così una maggiore semplicità di esecuzione, una presentazione dei dati funzionale ed una maggiore sicurezza relativamente all'integrità dei dati e all'aggiornamento degli stessi. I vincoli progettuali sono rappresentati in primo luogo dallo sviluppo in ambiente .NET, utilizzando la tecnologia Windows Presentation Foundation e il linguaggio di programmazione C#, in secondo luogo ,relativamente all'applicazione già esistente, dall'attenersi per quanto possibile alla sua logica e infine dall'implementare il tutto in modo tale che possa essere accessibile alla web application. Gli obiettivi di questo lavoro sono : - analisi dei requisiti da parte del committente; - analisi della situazione preesistente; - studio delle tecnologie .NET, e nel particolare di WPF e C#; - studio del funzionamento delle interazioni tra Database, applicazione e server; - progettazione del front-end; - realizzazione effettiva e compilazione su piattaforma .NET Framework 4.5; - test e distribuzione dell'applicazione. 4
  • 5. CAPITOLO 2 Analisi dei requisiti e della situazione esistente esistente 2.1 Intervista al committente Le richieste del committente per la nuova versione dell'applicazione sono : • effettuare un analisi degli oggetti ffettuare programmabili (viste , stored viste procedures , user defined functions functions) effettivamente utilizzati dall'applicazione al fine di effettuare un lavoro di pulizia nella base di dati dati; • effettuare l'upload di un documento relativo ad una determinata ffettuare pubblicazione nel server sul quale è presente un'istanza di ShareP SharePoint Server , aggiornando allo stesso tempo i valori presenti nella base di dati (Titolo del pdf e ID del documento) documento). Questo documento dovrà poi essere reperibile dalla web application che permette la visualizzazione dei contenuti dal web web; • effettuare la cancellazione di un documento (analogamente all'upload ffettuare bisogna gestire entrambi i "lati" : SharePoint e SQL Server) ed avere a disposizione opportuni controlli per verificare la presenza o meno di un 5
  • 6. documento, e potere gestire facilmente le azioni (upload , cancellazione, presentazione) relative ad esso; • poter esportare un file in formato Excel nel quale vengano riportati tutti i dati relativi al titolo della pubblicazione, all'anno , agli autori, alla denominazione e ai riferimenti, fornendo inoltre all'utente la possibilità di filtrare i risultati a suo piacimento prima di effettuare l'export; • eventuali accorgimenti per migliorare ulteriormente il front end. 2.2 Analisi della situazione esistente 2.2.1 Il database 2.2.1 La base di dati esistente è sita in un server remoto ( di3.units.it ) ed è composta da 27 tabelle, 63 viste e 133 stored procedures. Contiene tutti i dati inerenti la gestione del laboratorio come, ad esempio: dati anagrafici dei dipendenti, dati delle pubblicazioni, congressi, progetti e tesi. Le viste utilizzate dall'applicazione esistente sono: • ViewPubblicazioniRivista : mette in relazione le informazioni delle riviste con le informazioni dello staff; • ViewPubblicazioniCongressi : mette in relazione i le informazioni dello staff con il congresso relativo alla pubblicazione ; • Staff_View : una raccolta dei dati anagrafici dei membri dello staff . • ViewPubblicazioniRivista_Staff: variante della prima vista citata Le stored procedures utilizzate dall'applicazione esistente sono: 6
  • 7. sp_PubbStaff : utilizzata per visualizzare le pubblicazioni relative ad un membro dello staff. Riceve in input 2 parametri: @ID_staff è l'ID del componente dello staff, mentre @ID_output è un parametro che se settato a 0 fornisce sia le pubblicazioni presentate in un congresso che in una rivista, se settato ad 1 fornisce solo le pubblicazioni presentate in un congresso ed infine se settato a 2 fornisce solo le pubblicazioni presentate in una rivista • sp_PubbWeb: utilizzata per visualizzare le pubblicazioni presentate nel sito web del MOSE. Riceve in input un parametro @ID_SitoWeb , che rappresenta l'identificatore del sito web. Non sono state trovate invece User Defined Functions. Nella Figura 1 si riporta il Database Diagram della base di dati in questione : 7
  • 8. TBL_Options tblRiviste tblAnno TBL_PDFDocument Versions ID ID_rivista ID_Anno IDTitolo VersionId FolderPDFDocument Denominazione Anno NameFile Version RivistaInternazionale Id Referee UserName [Luogo pubblicazione] TimeStamp ISSN FinalizeTimeStamp Mode ModeStack Updates Notes tblProgetti tblTesiDettaglio tblTesi ID_Progetto ID_Tesi ID_Tesi Progetto DettaglioIT ID_Tipo SiglaProgetto DettaglioEN ArgomentoIT Anno_Inizio ArgomentoEN tblTesiStato Anno_Fine ID_Stato Collaborazione Finanziatore StatoTesi Correlatori ResponsabileLocale ID_Curriculum ResponsabileGlobale tblCurriculum Stato FinanziamentoLocale ID_Curriculum ID_Relatore FinanziamentoGlobale Curriculum Autore VIsualizzaSito CurriculumEN tblTipiTesi DataInizioTesi ID_Tipo TipoProgetto MEseLAurea Tipo imgproject AnnoLaurea summary Voto link tblStaffCongressi tblStaff ID_Staff tblStaffGruppi ID_Staff ID_Congresso ID_Gruppo Cognome Presentazione ID_Staff Nome Organizzazione Amministratore Attivo tblTItoloProgetto Partecipazione Username ID_progetto SuInvito Amministratore ID_titolo PhotoFileName PhoneNumber OfficeLocation Email tblGruppi tblCongressi Summary ID_Gruppo ID_Congresso Education Nome tblKeyword Denominazione ResearchActivity Note ID_Keyword Data ResearchProject Keyword Anno Collaborations CongressoIntenazionale Enabled Referee tblCollegamentoKeywordsTitolo tblStaffCorsi Id_Keyword tblTitoli ID_Staff tblStaffTitoli ID_Titolo ID_Corso ID_Titolo ID_Staff Autori Organizzatore ID_Titoli Riferimento ID_Stato ID_Rivista ID_Congresso tblCorsi Anno tblTipoPubbl ID_Corso ID_TipoPubb NomeCorso Titolo tblStatoTitolo TipoPubblicazione EnteOrganizzatore ID_Stato ID_tipoPubb TipoPubEnglish Periodo Stato ID_SitoW eb Class_TS Luogo Statoen ImpactFactor Class_PD Anno ID_Settore Figura 1 8
  • 9. 2.2.2 2.2.2 Analisi dell'applicazione esistente Questa applicazione è stata implementata utilizzando la tecnologia Windows Presentation Foundation (linguaggi C# e XAML). Il suo aspetto richiama quello delle applicazioni della suite Microsoft Office 2010. Alcuni studi sulla User Experience condotti dalle più importanti software house, hanno dimostrato come , attraverso l'uso di tecniche come l'eye tracking, l'utente tenda Figura 2 a leggere i contenuti delle pagine focalizzando maggiormente la propria attenzione su due linee orizzontali nella parte alta della pagina e su una linea verticale nella parte sinistra della pagina, secondo quello che è noto come schema ad F. Questo rappresenta un grande punto di forza per l'applicazione. La pagina visualizzata in Figura 2 è la home dell'applicazione , nella quale sono presenti link testuali che rimandano alle diverse pagine, e pulsanti (nella banda in grigio chiaro) che rimandano alle stesse. L'applicazione esistente è di tipo navigation-based nello stile di numerose altre navigation-based, applicazioni come Windows Explorer e Windows Media Player. Le pagine sulle quali è stata focalizzata maggiormente l'attenzione sono quelle relative alla gestione e alla presentazione dei dati relativi alle pubblicazioni pubblicazioni. 9
  • 10. Figura 3 Nella pagina relativa alle pubblicazioni si nota la presenza di 3 pulsanti: Dettaglio , Griglia e Staff Il primo di questi , lo si può già vedere nell'immagine, fornisce i Staff. dettagli della pubblicazione selezionata attraverso gli appositi controlli (Figura 3), il secondo fornisce una vista in un formato griglia, simulando l'interfaccia di una tabella di SQL Server (Figura 4) ed il terzo infine raggruppa, in formato-griglia, le pubblicazioni in base all'autore (Figura 5) ,che può essere selezionato attraverso una apposita listbox. Figura 4 10
  • 11. I pulsanti Export e Upload non svolgono ancora alcuna funzione. Figura 5 2.2.3 Data Binding Lo scambio di dati tra applicazione e database avviene grazie ad una stringa di connessione denominata MoseDBConnectionString. Il tipo di autenticazione utilizzata è Windows Authentication. <add name="MoseUXPrototype.Properties.Settings.MoseDBConnectionString" connectionString="Data Source=SERVERNAMESQLEXPRESS; Initial Catalog=MoseDB;Integrated Security=True" providerName="System.Data.SqlClient" /> Invece le interazioni tra applicazione e SharePoint (su server remoto) saranno implementate come richieste HTTP corredate delle opportune credenziali e verranno illustrate in seguito. 11
  • 12. Questa stringa si trova nel file ./MoseUXPrototype.exe.config.xaml , il quale è presente nel folder della versione distribuibile dell'applicazione. 2.2.4 Sharepoint Server e Web Application È presente inoltre una applicazione web che presenta le informazioni bibliografiche su un sito web. Questo sito web è stato creato utilizzando Microsoft SharePoint. SharePoint è un software lato server che permette la creazione di particolari siti web attraverso lo strumento software SharePoint Designer, con il quale è possibile gestire, tra le varie cose, un archivio di file che possono essere utilizzati dall'applicazione web. I file delle pubblicazioni infatti sono salvati in una apposita cartella ( www.mose.units.it/doc ). 12
  • 13. CAPITOLO 3 Progettazione 3.1 Principi generali di progettazione L'idea di fondo è sempre quella di conservare il layout dell'applicazione esistente, per quanto possibile, mantenendo vivace l'interfaccia e garantendone un facile e sicuro utilizzo da parte dell'utente. Per quanto riguarda sia l'upload che l'export si è deciso di implementare queste due funzionalità su due diverse finestre e non delle pagine : il motivo principale è finestre, il voler marcare la differenza sostanziale tra la gestione di file e la gestione di record. Si immagini di suddividere le funzionalità dell'applicazione su due livelli differenti: • lettura/scrittura di record (comunicazioni tra applicazione e base di dati) • gestione di file (upload / cancellazione) ed export (comunicazioni tra applicazione , SharePoint e base di dati ) L'intera applicazione esistente si presenta all'utente su un'unica finestra e l'utente può accedere ai diversi contenuti sfogliando tra le pagine di essa. Si è preferito invece implementare le nuove funzionalità per la gestione dei file , su finestre pop up , in modo tale da dare all'utente la sensazione di utilizzare uno strumento con vero e proprio. Si intende implementare quindi un Uploader ed un Exporter. 13
  • 14. Si intende inoltre permettere all'utente di gestire le connessioni e le credenziali per le interazioni web con i server, quindi sarà implementata un ulteriore finestra pop up per la consolle delle opzioni. Queste finestre saranno aperte da opportuni pulsanti posizionati nelle pagine dell'applicazione coerentemente con la loro funzione. 14
  • 15. CAPITOLO 4 Implementazione 4.1 Upload Si vuole caricare un file , relativo ad una determinata pubblicazione, su SharePoint ed aggiornare i record del database SQL Server che associano "id della id pubblicazione" con "titolo del pdf (Figura 6). titolo pdf" Figura 6 Il pulsante che permette di accedere a questa funzionalità è il pulsante Upload che è implementato nella pagina Pubblicazioni (Figura 3,4,5). Cliccando su tale pulsante si accede ad un nuova finestra : la console di upload una (Figura 7). L'interfaccia (figura 7) di questa finestra è stata implementata in modo tale da : interfaccia 15
  • 16. selezionare, attraverso una listBox, la pubblicazione per la quale si vuole effettuare l'upload del file; • cercare e selezionare il file da caricare; • selezionare il server e il percorso all'interno del quale caricare il documento; • di impostare le proprie credenziali (Username, Dominio e Password); • eseguire effettivamente l'upload. È presente inoltre un pulsante per effettuare un refresh della finestra. Figura 7 16
  • 17. La listbox che presenta le pubblicazioni esistenti viene popolata attraverso il metodo RiempiListbox(), il quale esegue una query di tipo select sul database descritto dalla stringa di connessione, si riporta di seguito il codice: public void RiempiListBox() { try { string query = "select ID_Titolo, Anno, Titolo from ViewPubblicazioniCongressi union select ID_Titolo,Anno,Titolo from ViewPubblicazioniRivista"; SqlConnection cn=new SqlConnection(Properties.Settings.Default.MoseDBConnectionString); SqlCommand cm = new SqlCommand(query); cm.Connection = cn; cn.Open(); SqlDataReader dr = cm.ExecuteReader(); while (dr.Read()) { listBox1.Items.Add(dr["ID_Titolo"]+", "+dr["Anno"]+", "+dr["Titolo"]); } dr.Close(); dr.Dispose(); } catch (SqlException ex) { MessageBox.Show(ex.Message); } } Il file dialog per la selezione del documento da caricare viene invece aperto cliccando sul pulsante Sfoglia (btnSfoglia) , si riporta di seguito il codice relativo: private void btnSfoglia_Click(object sender, RoutedEventArgs e) 17
  • 18. { Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); Microsoft.Win32.OpenFil Nullable<bool> result = dlg.ShowDialog(); > if (result == true true) { string filename = dlg.FileName; // aggiorno il contenuto della textbox textBox1.Text = filename; } } Una tipica esecuzione dell'upload è rappresentata in pseudo codice in Figura 8 : rappresentata Figura 8 Di seguito è riportato il codice dell'effettivo upload del documento: private bool Upload(string myFile) string { try 18
  • 19. { //UPLOAD SU SQL SERVER SqlConnection connection1 = new SqlConnection(Properties.Settings.Default.MoseDBConnectionString); string id = listBox1.SelectedItem.ToString(); string[] words = id.Split(','); //creo un array contenente i campi della selezione SqlCommand command = new SqlCommand("select IDTitolo from TBL_PDFDocument where IDTitolo=" + words[0]); command.Connection = connection1; connection1.Open(); //apro la connessione if (command.ExecuteScalar() != null){ connection1.Close(); } else { //se non c'è il documento nel db lo inserisco connection1.Close(); SqlCommand insertPdf = new SqlCommand("insert into TBL_PDFDocument values (" + words[0] + " , " + "'P" + returnID() + ".pdf')"); insertPdf.Connection = connection1; connection1.Open(); insertPdf.ExecuteNonQuery(); connection1.Close(); } connection1.Close(); //UPLOAD SU SHAREPOINT WebClient client = new WebClient(); //vado a reperire le credenziali dell'utente client.Credentials = new System.Net.NetworkCredential(textBox4.Text, passwordBox1.Password, textBox5.Text); string url="http://"+textBox2.Text+":" + textBox3.Text+"/"; client.UploadFile(url+"P"+returnID()+".pdf" , "PUT", myFile); client.Dispose(); MessageBox.Show("upload su sharepoint e su sql eseguito nDocumento : p"+returnID()+".pdf"); } catch (Exception err) { MessageBox.Show(err.Message); 19
  • 20. return false; } return true; } Analisi del codice [ metodo Upload ] Come si puo' notare il metodo è diviso fondamentalmente in due parti parti: l'aggiornamento di record su SQL Server e l'upload su SharePoint. Per quanto riguarda l'aggiornamento del record su SQL Server , le fasi di realizzazione sono: • creazione di un nuovo oggetto Connection (per poter comunicare con l'istanza di SQL Server) e in particolare attraverso l'utilizzo della MoseDBConnectionString. • reperimento dell'ID del documento selezionato dalla listbox , attraverso un metodo abbastanza rudimentale ma efficace: ovvero, viene effettuato un parsing dell'elemento selezionato (in formato stringa) al fine di estrarre il primo membro separato da virgola, ovvero l'ID della pubblicazione • costruzione della query in linguaggio Transact-SQL Questa query fornisce un risultato numerico, se il documento è già presente nella tabella (tabella delle pubblicazioni aventi già un file relativo caricato), altrimenti restituisce un valore nullo se questo file non è presente: • Se il record è già presente nella tabella, questo record non viene aggiornato; • Se il record non è presente viene eseguita una nuova query (statement di tipo INSERT ) che inserisce nella tabella (ID, nome del file). E' da notare che il nome del file , obbedisce ad uno standard dovuto ad un vincolo imposto dalla web application ,che lavora in parallelo con questa applicazione , in particolare il nome del file dovrà essere nel formato "Pxxxx.pdf" dove xxxx 20
  • 21. rappresenta l'id della pubblicazione (ad es. se l'id della pubblicazione è 16 , il documento si chiamerà "p0016.pdf"). Il metodo returnID() è un semplice metodo che utilizza l'ID della pubblicazione selezionata e crea la parte numerica del nome del file apponendo a sinistra dell'ID tanti zeri quanti sono necessari al fine di ottenere un nome con 4 cifre . private string returnID() { string id = listBox1.SelectedItem.ToString(); string[] words = id.Split(','); string returnstring; if (words[0].Length == 1) { returnstring = "000" + words[0]; return returnstring; } else if (words[0].Length == 2) { returnstring = "00" + words[0]; return returnstring; } else if (words[0].Length == 3) { returnstring = "0" + words[0]; return returnstring; } else { return words[0]; } } Per quanto riguarda l'upload del documento su SharePoint upload SharePoint: • in input si riceve il path del file (locale) da caricare; • viene creato un oggetto di tipo client che sarà il virtuale esecutore dell'upload; • a questo oggetto vengono assegnate le credenziali per la richiesta http , che saranno reperite dalle textBox (Username e Dominio) e dalla passwordBox (Password); • viene costruita la stringa dell'url nel quale sarà caricato il file andando a reperire le informazioni dalle textBox (Server e Folder); 21
  • 22. attraverso il metodo UploadFile dell'oggetto di tipo WebClient viene poi ttraverso caricato il documento su SharePoint , per mezzo di una richiesta HTTP di tipo PUT. 4.2 Cancellazione di files Figura 9 E' stata implementata un interfaccia utente per migliorare l'interazione con le funzionalità aggiunte e per dare all'utente la possibilità di cancellare un file pdf pdf. Nella schermata relativa al dettaglio della pubblicazione (Figura 9 ) sono stati aggiunti : • un indicatore che segnala se è presente o meno, nel database ,un file relativo alla pubblicazione selezionata selezionata; • un pulsante che rimanda alla finestra di upload; • un pulsante che permette, in caso di presenza di un file, di cancellarlo. presenza È più interessante concentrarsi sull'implementazione di quest'ultimo considerata la semplicità degli altri controlli citati. Come per l'upload del documento, la cancellazione dovrà essere effettuata su effettuata entrambi i "lati" (SQL Server e SharePoint) SQL SharePoint). 22
  • 23. Per il primo contesto viene eseguita una query del tipo : "delete from TBL_PDFDocument where IDTitolo= ". Mentre per la cancellazione in ambiente SharePoint viene eseguita una richiesta http di tipo DELETE, corredando la request delle credenziali opportune. Si riporta di seguito il codice utilizzato per la cancellazione del documento. Figura 10 private void DeletePDF() { try { //CANCELLAZIONE SU SQL SERVER System.Windows.Window loading = new System.Windows.Window { Height = 100, Width = 200, WindowStartupLocation = WindowStartupLocation.CenterScreen, WindowStyle = WindowStyle.None }; loading.Content = new TextBlock { Text = "Please Wait", FontSize = 30, FontWeight = FontWeights.Bold, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; loading.Show();// Mostra finestra di attesa tblTitoli currentTitle = (tblTitoli)this.MasterView.CurrentItem; 23
  • 24. int IDTitolo = currentTitle.ID_Titolo; SqlConnection connection1 = new SqlConnection(Properties.Settings.Default.MoseDBConnectionString); SqlCommand command = new SqlCommand("delete from TBL_PDFDocument where IDTitolo=" + IDTitolo); command.Connection = connection1; connection1.Open(); command.ExecuteNonQuery(); connection1.Close(); label1.Content= SetLabel(); //CANCELLAZIONE SU SHAREPOINT string nomeFile = "P" + returnID() + ".pdf"; string url = "http://"+Properties.Settings.Default.Server+":" +Properties.Settings.Default.Sito +"/"+nomeFile; //server:sito HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url); req.Credentials = new System.Net.NetworkCredential(Properties.Settings.Default.Username, Properties.Settings.Default.Password, Properties.Settings.Default.Dominio); req.Method="DELETE"; HttpWebResponse response = (HttpWebResponse)req.GetResponse(); loading.Close(); MessageBox.Show("Il documento : P" + returnID() + ".pdf è stato eliminato"); } catch (Exception e) { MessageBox.Show(e.Message); } } 24
  • 25. 4.3 Opzioni Utente Figura 11 Il pulsante Opzioni (Figura 11) permette all'utente di visualizzare una nuova finestra (Figura 12) all'interno della quale sarà possibile impostare dei valori di default per le credenziali, in modo tale da non dover selezionare il server ed autenticarsi ogni qualvolta si dovesse caricare o cancellare un documento da SharePoint. Queste impostazioni di configurazione, sono salvate, al primo utilizzo dell'applicazione, nel file MoseUXPrototype,xml.config , mentre successivamente in automatico, l'applicazione andrà a reperire questi settaggi da un file presente in C:/Users/NomeUser/AppData/Local/ che viene creato al primo utilizzo di questa . All'interno di questa finestra, il pulsante Conferma esegue una modifica del valore delle stringhe di default presenti nelle file di configurazione dell'applicazione: • Properties.Settings.Default.Server, • Properties.Settings.Default.Sito, • Properties.Settings.Default.Username, • Properties.Settings.Default.Password, • Properties.Settings.Default.Dominio. 25
  • 26. Figura 12 4.4 Export Questa funzione permette all'utente di esportare in un foglio elettronico Excel i dati delle pubblicazioni. In particolare le informazioni che possono essere reperite sono: • Anno di pubblicazione; • Titolo ; • Autore/i ; • Riferimento ; • Congresso (nel quale è stata presentata la pubblicazione) . Sono presenti inoltre alcuni filtri aggiuntivi che permettono di raffinare la ricerca: • intervallo di tempo (anni); • tipo di pubblicazione; • membro dello staff (autore). Come si può notare nell'immagine (Figura 13), l'utente può scegliere se inserire o meno ognuno dei 5 campi in alto a sinistra , selezionando o deselezionando le checkbox. 26
  • 27. Il processo di esportazione in formato Excel dei dati richiesti dall'utente si svolge in 4 passaggi fondamentali: 1. operazioni preliminari (ad es. popolamento combobox) 2. costruzione della query da eseguire sulla base di dati, in base ai campi selezionati dall'utente 3. compilazione di un Figura 13 file di testo semplice , utilizzando il delimitatore tab (t), utilizzando i dati di output della query 4. apertura del file di testo da parte dell'applicazione Excel riconoscendo il tab Primo passo La comboBox relativa ai membri dello staff si popola grazie ad una query eseguita sulla base di dati, questa query estrapola Nome e Cognome dei membri dello staff public void LoadCmbStaff() { try { 27
  • 28. SqlConnection cn = new SqlConnection(Properties.Settings.Default.MoseDBConnectionString); SqlCommand cm = new SqlCommand("SELECT Cognome , Nome FROM tblStaff"); cm.Connection = cn; cn.Open(); SqlDataReader dr = cm.ExecuteReader(); while (dr.Read()) { //popolamento della combobox cmbStaff.Items.Add(dr["Cognome"]+" , "+dr["Nome"]); } dr.Close(); dr.Dispose(); } catch (SqlException ex) { MessageBox.Show(ex.Message); } } Secondo passo L'idea che sta alla base di questa implementazione è quella di analizzare elemento per elemento (Titolo, Autore, Anno, ecc ) le richieste dell'utente e costruire coerentemente la query. L'algoritmo per la costruzione della stringa , che sarà il contenuto della query si costituisce di 3 steps fondamentali, in base ai campi che vengono selezionati e in base ai filtri che vengono attivati: • costruzione della stringa "SELECT …FROM…" • costruzione della stringa "WHERE …" • coordinamento del tutto e costruzione della stringa completa 28
  • 29. Nelle pagine seguenti viene riportato l'algoritmo in pseudocodice (Figure 14 e 15): Stringa = «SELECT» Stringa1 = «WHERE» F F Anno is checked IF Dal != null T T Stringa1 = Stringa1 + Stringa = Stringa + «Anno» «ANNO >= Dal » F F Titolo is checked IF Al != null T T Stringa1 = Stringa1 + Stringa = Stringa + «Titolo» «ANNO <= Al » F F Autori is checked IF Autore != Tutti T T Stringa1 = Stringa1 + Stringa = Stringa + «Autori» «AUTORI LIKE ‘CognomeAutore’» F Riferimento is checked strWhere =14 Figura Stringa1 T Stringa = Stringa + «Riferimento» F Denominazione is checked T Stringa = Stringa + «Denominazione» strSelect = Stringa Figura 14 29
  • 30. X = tipoPubblicazione T X==1 Query = strSelect + «FROM dbo.ViewPubblicazioniCongressi» +strWhere F T X==2 Query = strSelect + «FROM dbo.ViewPubblicazioniRiviste» +strWhere F T Query = strSelect + «FROM dbo.ViewPubblicazioniCongressi» +strWhere X==0 + «UNION» + strSelect + «FROM dbo.ViewPubblicazioniRiviste» +strWhere F Figura 15 Il passaggio finale (Figura 15) è motivato dal fatto che è possibile che una pubblicazione sia riferita contemporaneamente ad una rivista e ad un congresso e congresso, quindi bisogna fornire all'utente la possibilità di scegliere che tipo di dato visualizzare , se la prima, se la seconda o se entrambe. Di seguito si riporta il metodo per la creazione della parte iniziale della query: string CorpoStringCongressi = " FROM dbo.ViewPubblicazioniCongressi "; string CorpoStringRiviste = " FROM dbo.ViewPubblicazioniRivista "; private string CostruisciQueryIniziale() { string SelectBase = "SELECT "; string Supporto = SelectBase; if (checkBoxAnno.IsChecked == true) { /* Questi IF interni servono ad evitare il caso in cui ci si trovi ad avere una Select del tipo: >> SELECT , NOME << (virgola in mezzo) */ if (Supporto == "SELECT ") { Supporto = Supporto + " Anno ";} else { Supporto = Supporto + ", Anno "; 30
  • 31. } } if (checkBoxTitolo.IsChecked == true) { if (Supporto == "SELECT ") { Supporto = Supporto + " Titolo "; } else { Supporto = Supporto + ", Titolo "; } } if (checkBoxAutori.IsChecked == true) { if (Supporto == "SELECT ") { Supporto = Supporto + " Autori "; } else { Supporto = Supporto + ", Autori "; } } if (checkBoxRiferimento.IsChecked == true) { if (Supporto == "SELECT "){ Supporto = Supporto+" Riferimento"; } else { Supporto = Supporto + ", Riferimento "; } } if (checkBoxCongresso.IsChecked == true) { if (Supporto == "SELECT "){ Supporto =Supporto+" Denominazione";} else { Supporto = Supporto + ", Denominazione "; } } return Supporto; } 31
  • 32. Di seguito si riporta il codice relativo allo statement WHERE della query: private string CostruisciQueryWhere() { string Original = " WHERE "; string Supporto = Original; if (cmbStaff.Text != null && checkBoxStaff.IsChecked==false ) { //nella combobox sono presenti COGNOME,NOME io vado ad utilizzare solo //il cognome facendo un parsing della stringa cmbbox.text string autore =cmbStaff.Text.ToString(); string[] arr = autore.Split(','); if (Supporto == Original) //per risolvere il problema di "WHERE , //NOME STAFF.." SINTASSI T-SQL { Supporto = Supporto + " Autori LIKE '%" + arr[0] + "%' "; } else { Supporto = Supporto + " AND " + " Autori LIKE '%" + arr[0] + "%' "; } } if ( textBoxDal.Text!=null && textBoxDal.Text!=""){ if (Supporto == Original) { Supporto = Supporto + " Anno >= "+ textBoxDal.Text + " "; } else { Supporto = Supporto + " AND " + " Anno >= " + textBoxDal.Text + " "; } } if (textBoxAl.Text != null && textBoxAl.Text != "") { 32
  • 33. if (Supporto == Original) { Supporto = Supporto + " Anno <= " + textBoxAl.Text + " "; } else { Supporto = Supporto + " AND " + " Anno <= " + textBoxAl.Text + " "; } } //passaggio finale if (Supporto == Original) { return ""; } else { return Supporto; } } Infine si riporta il codice relativo alla concatenazione delle diverse sottostringhe e alla formazione query completa: private string CostruisciQuery() { string vuota = ""; string TotalQuery = vuota; if (cmbTipoPubb.SelectedIndex == 0) { TotalQuery = TotalQuery + CostruisciQueryIniziale() + " " + CorpoStringCongressi + CostruisciQueryWhere() + " UNION " + CostruisciQueryIniziale() + CorpoStringRiviste + CostruisciQueryWhere(); } else if (cmbTipoPubb.SelectedIndex == 1) 33
  • 34. { TotalQuery = TotalQuery + CostruisciQueryIniziale() + CorpoStringCongressi + CostruisciQueryWhere(); } else if (cmbTipoPubb.SelectedIndex == 2) { TotalQuery = TotalQuery + CostruisciQueryIniziale() + CorpoStringRiviste + CostruisciQueryWhere(); } else { TotalQuery = TotalQuery + CostruisciQueryIniziale() + CorpoStringCongressi + CostruisciQueryWhere() + " UNION " + CostruisciQueryIniziale() + CorpoStringRiviste + CostruisciQueryWhere(); } Console.WriteLine(TotalQuery); if (TotalQuery != vuota) { return TotalQuery; } else return vuota; } Terzo passo Di seguito si riporta il codice per la costruzione del file di testo: public string generaCsv(int colonne, string sqlCommand) { string csvFile = ".//TempFile.txt"; try { string connectionString = Properties.Settings.Default.MoseDBConnectionString; using (SqlConnection connection = new SqlConnection(connectionString)) { 34
  • 35. try { connection.Open(); } catch (System.Data.SqlClient.SqlException ex) { // handle return ""; } using (SqlDataAdapter adapter = new SqlDataAdapter(sqlCommand, connection)) { using (System.Data.DataTable table = new System.Data.DataTable("tbl")) { adapter.Fill(table); StringBuilder commaDelimitedText = new StringBuilder(); foreach (DataRow row in table.Rows) { for (int i = 0; i < colonne; i++) { /*Qui era sorto un problema, il mio "Generatore di Csv" , quando trovava 2 spazi consecutivi li considerava come una nuova colonna. risolto usando espressione regolare */ row[i] = Regex.Replace(row[i].ToString(), @"s+", " "); } switch (colonne) { case 1: { string value = string.Format("{0}", row[0]); commaDelimitedText.AppendLine(value); File.WriteAllText(csvFile,commaDelimitedText.ToString()); break; } case 2: { 35
  • 36. string value=string.Format("{0}t{1}", row[0], row[1]); commaDelimitedText.AppendLine(value); File.WriteAllText(csvFile,commaDelimitedText.ToString()); break; } case 3: { string value = string.Format("{0}t{1}t{2}", row[0], row[1], row[2]); commaDelimitedText.AppendLine(value); File.WriteAllText(csvFile,commaDelimitedText.ToString()); break; } case 4: { string value = string.Format("{0}t{1}t{2}t{3}",row[0], row[1], row[2], row[3]); commaDelimitedText.AppendLine(value); File.WriteAllText(csvFile,commaDelimitedText.ToString()); break; } case 5: { string value = string.Format("{0}t{1}t{2}t{3}t{4}", row[0], row[1], row[2], row[3], row[4]); commaDelimitedText.AppendLine(value); File.WriteAllText(csvFile,commaDelimitedText.ToString()); break; } } } } } } 36
  • 37. } catch (Exception ex) { System.Windows.MessageBox.Show(ex.Message); } return csvFile; } Analisi del codice Questo metodo sfrutta il metodo Contacolonne() che restituisce il numero di colonne che andranno a formare la tabella in formato Excel, il risultato di questo metodo è passato come input (int colonne). È necessario contare le colonne perché la sintassi del comando string.Format(..) permette di stabilire un unico tipo di formattazione. L'input string sqlCommand è invece la query che sarà eseguita sulla base di dati. Sono stati identificati 5 casi possibili in base al risultato del metodo Contacolonne(). Il riempimento del file di testo è effettuato attraverso un ciclo , all'interno del quale vengono copiati nel file i dati della tabella (risultato della query) apponendo un delimitatore /t eccezion fatta per l'ultima colonna ( /n). /t, Questo file viene salvato con il nome TempFile.txt nella cartella in cui è presente l'eseguibile dell'applicazione, ed ogni qual volta verrà eseguita un'operazione di questo tipo lo stesso file verrà riscritto prevenendo problemi di capienza di memoria o di semplice esubero di file non necessari. Quarto passo Una volta creato il file di testo viene aperto un foglio elettronico Excel il quale attraverso l'impostazione che prevede il riconoscimento del delimitatore tab ( "/t" ) popola le sue celle in base a quanto contenuto nel file di testo. 37
  • 38. Successivamente verranno inserite le intestazioni delle colonne attraverso il metodo generaIntestazioniExcel(). Il metodo CSVtoExcel prende in input: • il path del file che si vuole aprire; • il foglio Excel nel quale aprire il file; • le coordinate della cella da cui iniziare la popolazione delle celle; • un array di tipi di dato per le rispettive colonne; • un valore booleano che che imposta l'autodimensionamento (o meno) delle colonne. Di seguito si riporta il codice del metodo in questione: public void CSVtoExcel(string importFileName, Excel.Worksheet destinationSheet, Excel.Range destinationRange, int[] columnDataTypes, bool autoFitColumns) { destinationSheet.QueryTables.Add( "TEXT;" + System.IO.Path.GetFullPath(importFileName),destinationRange, Type.Missing); destinationSheet.QueryTables[1].Name = System.IO.Path.GetFileNameWithoutExtension(importFileName); destinationSheet.QueryTables[1].FieldNames = true; destinationSheet.QueryTables[1].RowNumbers = false; destinationSheet.QueryTables[1].FillAdjacentFormulas = false; destinationSheet.QueryTables[1].PreserveFormatting = true; destinationSheet.QueryTables[1].RefreshOnFileOpen = false; destinationSheet.QueryTables[1].RefreshStyle = XlCellInsertionMode.xlInsertDeleteCells; destinationSheet.QueryTables[1].SavePassword = false; destinationSheet.QueryTables[1].SaveData = true; destinationSheet.QueryTables[1].AdjustColumnWidth = true; destinationSheet.QueryTables[1].RefreshPeriod = 0; destinationSheet.QueryTables[1].TextFilePromptOnRefresh = false; //l'id 65001 rappresenta l'id della piattaforma che decodifica i contenuti in UTF-8 destinationSheet.QueryTables[1].TextFilePlatform = 65001; destinationSheet.QueryTables[1].TextFileStartRow = 1; 38
  • 39. destinationSheet.QueryTables[1].TextFileParseType = XlTextParsingType.xlDelimited; destinationSheet.QueryTables[1].TextFileTextQualifier = XlTextQualifier.xlTextQualifierDoubleQuote; destinationSheet.QueryTables[1].TextFileConsecutiveDelimiter = false; destinationSheet.QueryTables[1].TextFileTabDelimiter = true; destinationSheet.QueryTables[1].TextFileSemicolonDelimiter = false; destinationSheet.QueryTables[1].TextFileCommaDelimiter = false; destinationSheet.QueryTables[1].TextFileSpaceDelimiter = false; destinationSheet.QueryTables[1].TextFileColumnDataTypes = columnDataTypes; destinationSheet.QueryTables[1].Refresh(false); if (autoFitColumns == true) { destinationSheet.QueryTables[1].Destination.EntireColumn.AutoFit(); } } Mentre il pulsante che aziona questo meccanismo agisce in questo modo: viene aperta inizialmente una finestra che avvisa l'utente di attendere l'esecuzione del processo, viene aperto un foglio Excel (non visibile ancora all'utente), viene generato il file di testo sopra citato, viene eseguito il metodo CsvToExcel , vengono generate le intestazioni per le colonne del file Excel , dunque sparisce la finestra di attesa e viene visualizzato il file. private void button1_Click(object sender, RoutedEventArgs e) { try { System.Windows.Window loading = new System.Windows.Window { Height = 100, Width = 200, WindowStartupLocation = WindowStartupLocation.CenterScreen, WindowStyle = WindowStyle.None }; 39
  • 40. loading.Content = new TextBlock { Text = "Please Wait", FontSize = 30,FontWeight = FontWeights.Bold, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; loading.Show(); Excel.Application xla = new Excel.Application(); Excel.Workbook wb = xla.Workbooks.Add(Excel.XlSheetType.xlWorksheet); Excel.Worksheet ws = (Excel.Worksheet)xla.ActiveSheet; xla.Visible = false; int cln = contacolonne(); string filepath = generaCsv(cln, CostruisciQuery()); CSVtoExcel(filepath, (Excel.Worksheet)(wb.Worksheets[1]), (Excel.Range)(((Excel.Worksheet)wb.Worksheets[1]).get_Range("$A$2")), new int[] { 2, 2, 2, 2, 2 }, true); //Come ultima cosa inserisco le intestazioni delle colonne List<string> lista = generaIntestazioniExcel(); for (int i = 0; i < cln; i++) { ws.Cells[1, i + 1] = lista[i]; } xla.Visible = true; wb.ActiveSheet.QueryTables[1].Delete(); loading.Close(); } catch (Exception myex) { MessageBox.Show(myex.Message); } } 40
  • 41. Il risultato di un possibile Export può essere: (a) Creazione del file txt, non visibile all'utente (b) Apertura del file da parte di Excel 4.5 Implementazioni di carattere generale Sempre nell'ottica di migliorare ulteriormente l'interfaccia utente per renderla più funzionali ai bisogni del committente sono implementate alcune features , di minor rilevanza per, ma di indubbia utilità per l'utente: • nella pagina relativa alle pubblicazioni in formato-griglia, viene aggiunta una colonna che presenta il nome del documento pdf , se presente, o nulla in caso contrario (Figura 16); • per le pagine "PubblicationGrid" e "PubblicationCustom" è stato riscritto , in modo coerente con le modifiche apportate, il codice che permette all'utente di accedere ai dettagli della pubblicazione selezionata cliccando due volte sulla riga della griglia; • sono stati abilitati, nella home page, i link testuali che rimandano alle pagine relative (come Upload e Export) e sono stati modificati i label relativi alla versione ed al nome dell'applicazione. 41
  • 42. Figura 16 42
  • 43. CAPITOLO 5 Conclusioni 5.1 Possibili miglioramenti Svolgendo questo lavoro si è pensato inoltre a possibili miglioramenti , che potrebbero essere sviluppati in futuro. Tra i quali quelli di maggior rilevanza sono: • funzionalità di import: permettere all'utente di effettuare un importazione di dati, da tabella excel, in modo tale da non dover inserire i record manualmente (ad esempio : nome, cognome e dati anagrafici di un nuovo membro dello staff). Questa feature alleggerirebbe ancor di più il lavoro per l'utente che attualmente deve inserire i nuovi dati , pur sempre via applicazione, ma manualmente • versione web dell'applicazione, completamente svincolata quindi dal Pc dell'utente . Possibile utilizzo della tecnologia ASP.NET 5.2 Conclusioni Features implementate Upload PDF Cancella PDF Export Gestione Credenziali 43
  • 44. L'obiettivo di implementare tutte le funzionalità richieste dal committente è stato raggiunto. Per quanto riguarda invece le conoscenze e le abilità acquisite, sono stati raggiunti i seguenti obiettivi: • raccolta dei requisiti mediante intervista al committente • analisi della situazione esistente • studio di .NET e di Windows Presentation Foundation • studio di Database Relazionali • studi sulle comunicazioni tra le diverse entità (server, applicazione, db) L'applicazione ora non è più in fase di test (beta), ma è a tutti gli effetti in uso , nella sua versione 2.0 2.0. Righe di codice scritte : • C# : 700 • XAML : 300 44
  • 45. Bibliografia • http://msdn.microsoft.com/en-us/library/aa970268.aspx (Introduction to WPF - MSDN) • M. Miotto, "Progettazione e sviluppo di una applicazione per la gestione di dati bibliografici in ambiente .NET " , Tesi per corso di laurea triennale in Ingegneria Informatica (Università degli studi di Trieste) • Dispense del corso di Basi di Dati tenuto dal Dott. Fermeglia presso l'Università degli Studi di Trieste • http://msdn.microsoft.com/it-it/library/ms254978(v=vs.110).aspx • http://stackoverflow.com/questions/8947410/using-settings-settings-in-a- windows-wpf-app-vs2010 • http://www.codeproject.com/Articles/19509/Write-Data-to-Excel-using-C • Adam Nathan - WPF 4 Unleashed - Pearson Education (US) – 2010 • http://blogs.msdn.com/b/pietrobr/archive/2007/09/07/parliamo-di-linq- parte-3.aspx • http://msdn.microsoft.com/it-it/vcsharp/cc788743(en-us).aspx 45