Blog Stats
  • Posts - 129
  • Articles - 1
  • Comments - 163
  • Trackbacks - 4

 

lunedì 17 novembre 2008

Sharepoint Workflow: Impostare i permessi sul task

In questo post c'e' indicata una soluzione "built-in" per impostare i permessi su un task creato all'interno di un workflow disegnato con VS2008.

La soluzione alternativa sarebbe quella di scrivere del codice custom in un eventhandler.

Molto utile.

del.icio.us Tags: ,,

Sharepoint Dispose Patterns

Segnalo questo post in cui vengono indicate, tramite esempi, le best practice per quanto riguarda il "dispose" di SPSite e SPWeb.

Chi sviluppa in Sharepoint sa benissimo quanto la non corretta "chiusura" di questi oggetti possa provocare dei memory leaks che alla lunga possono incidere negativamente sulle prestazioni.

del.icio.us Tags: ,,

domenica 9 novembre 2008

ASP.NET MVC first step

Ieri mi sono visto la sessione su MVC(PC21 ASP.NET MVC: A New Framework for Building Web Applications) tenuta allo scorso PDC 2008 da Phil Haack.

Fino a questo momento non avevo avuto tempo per poter approfondire il discorso MVC, pur cercando di seguire i post di Scott Guthrie e Simone, ma devo dire che questa sessione mi ha dato veramente tanti spunti di ispirazione.

Certo, con tutti gli avvertimenti del caso tra cui il fatto che MVC non sostituisce web form ma rappresenta un approccio utile in alcuni scenari.

Consiglio a tutti di guardarsi questa registrazione.

 

NB. per la prima volta mi sono visto una sessione registrata non dal portatile o dal monitor, ma direttamente dal mio televisore lcd 32 passando in streaming attaverso la PS3.Spettacolare, era come essere li :)

 

del.icio.us Tags: ,

lunedì 27 ottobre 2008

Creare ListTemplate e ListInstance tramite Features

In questo sintetico post, che voglio utilizzare più che tutto come promemoria personale, evidenzio alcuni tips utili a chi sviluppa applicazioni Sharepoint.

In particolare si tratta di alcune note che riguardano lo svilippo di List Templates con l'esigenza di creazione automatica della lista durante l'attivazione della feature:

  • Creare due features distinte, una per il template della lista(ListTemplate) ed una per l'istanza della lista(ListInstance). Eventualmente avrò anche una terza feature dove creo i 
    content types ed i fields.

  • Per velocizzare lo sviluppo del template posso utilizzare VSeWSS 1.2, tramite il progetto List Definition.

    Personalmente creo il template con VSeWSS 1.2, ma migro poi i files che mi servono su un progetto di tipo "empty feature" creato tramite STSDEV 1.3, in quanto quest'ultimo mi da la massima flessibilità nel gestire la struttura della feature.

  • Nella feature di definizione del template di lista posso evitare di portarmi dietro i file aspx (editform, dispform, newform, etc...) generati da VSeWSS 1.2 se questi non sono diversi da quelli di default. Per questo occore modificare il file Schema.xml nel modo seguente:

    - nelle Views, per ogni View aggiungo l'attributo SetupPath="pages\viewpage.aspx"
    - nelle Forms, per ogni Form aggiungo l'attributo SetupPath="pages\form.aspx"

  • Nella feature che definisce l'istanza della lista devo specificare TemplateType e Id altrimenti la lista non viene creata.
    Inoltre devo specificare il valore di FeatureId uguale all' id della feature che definisce il template di lista.      
        <ListInstance
            Id="MyTaskListInstance"
            FeatureId="70398CC4-A413-11DD-8204-52BE56D89593"
            Title="My Tasks"
            Url="Lists/MyTasks"
            TemplateType="107" />
del.icio.us Tags: ,,

martedì 21 ottobre 2008

Sharepoint CAML Query with multiple "<Or>" or "<And>"

Sembra strano, ma se dovete impostare una query CAML per Sharepoint usando l' Object Model e la query contiene più di due espressioni in "<And>" oppure "<Or>", avrete di ritorno uno strano errore che potrebbe bloccarvi per molto.

Ho trovato fortunamente questo utilissimo post dove viene anche descritto un possibile workaround.

Completo solo il post in questione aggiungendo che nella query CAML devo avere al massimo due espressioni per ogni "<Or>" o "<And>", ma all'interno della stessa "<Where>" è possibile aggiungere tutti gli "<And>" e gli "<Or>" che vogliamo.
Quindi non è necessario creare annidamenti ricorsivi ed è possibile rendere l'intera espressione CAML più leggibile e semplice.

Es. abbiamo una query con 6 "Or" che per evitare l'errore dovrebbe essere scritta nel modo seguente:

<Where>
  <Or>
    <Eq><FieldRef Name='Title'/><Value Type='Text'>***</Value></Eq>
    <Eq><FieldRef Name='ProductCode'/><Value Type='Text'>***</Value></Eq>
  </Or>
  <Or>
    <Eq><FieldRef Name='ProductDescription'/><Value Type='Text'>***</Value></Eq>
    <Eq><FieldRef Name='ID'/><Value Type='Number'>***</Value></Eq>
  </Or>
</Where>

Spero sia utile.

del.icio.us Tags: ,,

domenica 21 settembre 2008

JQuery, TabContainer e UpdatePanel per la notifica di modifica di una form

Durante la creazione di form è spesso necessario implementare un meccanismo che consenta di avvisare l'utente che i dati nella form sono cambiati ed è quindi necessario procedere al salvataggio.

Questo succede per esempio quando ho form complesse fatte a tab ed il passaggio da un tab all'altro presuppone che un messaggio avvisi l'utente che ci sono dei campi variati nel tab che si sta abbandonando ed è quindi necessario aggiornarlo.

Ipotizziamo uno scenario in cui utilizziamo ASP.NET ed Ajax dove avremo un UpdatePanel con al suo interno il TabContainer dell' AjaxControlToolkit. Ogni TabContainer conterrà la propria FormView con tutti i controlli di input necessari:

...
<ajaxToolkit:TabContainer runat="server" ID="TabContainerControl" OnClientActiveTabChanged="clientActiveTabChanged">
  <ajaxToolkit:TabPanel ID="Tab1" runat="server" HeaderText="Tab 1">
    <ContentTemplate>
      <div id="Tab1">
        <!--...ascx, formview, ...-->
      </div>
    </ContentTemplate>
  </ajaxToolkit:TabPanel>
...

Prima di tutto agganciamo l'evento client OnClientActiveTabChanged del TabContainer ad una funzione javascript dove:
  1) verificherò che qualcosa nel tab da cui provengo è cambiato
  2) se ci sono dati variati e l'utente conferma, aggiorno il tab da cui provengo

function clientActiveTabChanged(sender, args) {
  var activeIndex = sender.get_activeTabIndex();
  if (tabChanged) {
    if (window.confirm('Sono stati modificati dei dati.Prima di passare alla sezione successiva è necessario salvare le modifiche.\n\nClicca \'OK\' per procedere con il salvataggio.')) {
          __doUpdateTab(exActiveIndex);
        }
      }
  
  tabChanged = false;
  exActiveIndex = activeIndex;
}

La funzione __doUpdateTab si occupa di effettuare una chiamata di tipo postback dove verrà gestito, lato server, l'aggiornamento del tab.La variabile javascript tabChanged indica se ci sono state modifiche in un tab.

La cosa interessante ed anche la più importante di tutto il post è l'utilizzo di JQuery per generare velocemente gli eventi di notifica su tutti i controlli di tipo input per ciascun tab:

            jQuery(document).ready(
              function() {
                  jQuery('#Tab1 :input').bind('change',
                function(event) {
                    tabChanged = true;
                });
              });
 

Con queste poche righe di javascript, utilizzando JQuery, abbiamo agganciato l'evento client di change su tutti i controlli di tipo input che ci sono all'interno di un div che ha per id Tab1, che nel nostro caso corrisponde al div contenitore del primo TabPanel.

IMPORTANTE: se si usa tutto quando descritto all'interno di un UpdatePanel(per esempio posizionato all'interno di una master page) succede che dopo un qualsiasi postback il javascript relativo agli eventi di change non risponde più. E' quindi necessario registrare tutti i javascripts sopra direttamente da codice, utilizzando le procedure corrette.

NB. ho preso spunto da questo post di Rick Strahl.

del.icio.us Tags: ,,

lunedì 8 settembre 2008

SSIS Package deployment security

Per chi sviluppa packages con Sql Server Integration Services , segnalo questo utile articolo del supporto Microsoft dove vengono descritti i problemi realtivi alla security che si potrebbero avere quando si effettua il deploy e l'esecuzione dei packages su una macchina differente da quella di sviluppo.

L'approccio che preferisco personalmente è quello di avvalermi di file xml di configurazione e lasciare i package con il ProtectionLevel impostato su DontSaveSensitive, anche se questa scelta dipende molto dalla tipologia di progetto e dalla configurazione di produzione che si avrà poi a disposizione.

del.icio.us Tags: ,

giovedì 28 agosto 2008

SubSonic 2.1 Stored Procedure Bug

SubSonic è un tool open(ci sono i sorgenti inclusi nel package di installazione) che fornisce un framework di accesso ai dati basato sul pattern ActiveRecords.

Risulta quindi una soluzione molto utile, veloce e semplice da utilizzare in progetti in cui non è un requisito l'avere una architettura per forza di cose "loosely coupled"(anche se da questo post l'autore dimostra come anche con SubSonic posso comunque realizzare architetture basate per esempio sul pattern Repository e mantenendo le indipendenze tra i vari layers).

L'ultima versione, la 2.1, presenta un bug durante l'esecuzione di stored procedures che abbiano parametri di tipo decimal con impostati lo "scale"(es. decimal(18,2)).

Qui c'e' il post relativo alla segnalazione, con relativa conferma di fix.

Purtroppo non ho trovato i sorgenti di queste ultime modifiche, che sembra saranno rilasciati in una futura versione 2.1.1.

La soluzione più veloce per me è stata quella di caricare con VS2008 i sorgenti di SubSonic(caricati come dicevo all'inizio durante l'installazione) e cercare di trovare il rimedio al bug in questione. Ecco dove correggere(la parte in bold), nella classe SubSonic.SqlDataProvider:

    private static void AddParams(SqlCommand cmd, QueryCommand qry)
        {
            if(qry.Parameters != null)
            {
                foreach(QueryParameter param in qry.Parameters)
                {
                    SqlParameter sqlParam = new SqlParameter(param.ParameterName, Utility.GetSqlDBType(param.DataType));
                    sqlParam.Direction = param.Mode;

                    //output parameters need to define a size
                    //our default is 50
                    if(sqlParam.Direction == ParameterDirection.Output || sqlParam.Direction == ParameterDirection.InputOutput)
                        sqlParam.Size = param.Size;

                    if(param.Precision != null)
                        sqlParam.Precision = Convert.ToByte(param.Precision);
                    if(param.Scale != null)
                        sqlParam.Scale = Convert.ToByte(param.Scale);

                    //fix for NULLs as parameter values
                    if(param.ParameterValue == null || Utility.IsMatch(param.ParameterValue.ToString(), "null"))
                        sqlParam.Value = DBNull.Value;
                    else if(param.DataType == DbType.Guid)
                    {
                        string paramValue = param.ParameterValue.ToString();
                        if(!String.IsNullOrEmpty(paramValue))
                        {
                            if(!Utility.IsMatch(paramValue, SqlSchemaVariable.DEFAULT))
                                sqlParam.Value = new Guid(param.ParameterValue.ToString());
                        }
                        else
                            sqlParam.Value = DBNull.Value;
                    }
                    else
                        sqlParam.Value = param.ParameterValue;

                    cmd.Parameters.Add(sqlParam);
                }
            }
        }

 

E' sufficiente ricompilare ed utilizzare il nuovo assembly.

del.icio.us Tags:

mercoledì 6 agosto 2008

Do not read from the Sharepoint Database

Dal momento che mi capita spesso di spiegare ai clienti che non è consigliato e non è "best practice" interrogare direttamente i database di Sharepoint(bisogna in invece utilizzare il suo completo Object Model via codice), oggi ho finalmente trovato anche un post che ne spiega le motivazioni in modo molto più "ufficiale":

http://www.sharepoint-tips.com/2008/08/do-not-read-from-sharepoint-database.html

del.icio.us Tags:

mercoledì 30 luglio 2008

Sharepoint Custom Editor Web Part development

Volevo segnalare due post interessanti per chi sviluppa web parts per Sharepoint(WSS 3.0 / MOSS 2007) ed ha la necessita di dover personalizzare la sezione di editing della web part.

 

EditorPart 101 descrive in breve come essere subito operativi e realizzare la propria EditorPart.

Creating custom editor parts for a SharePoint webpart , a complemento del primo post, oltre a descriviere come realizzare EditorPart illustra anche la soluzione ad alcuni problemi di sviluppo che hanno fatto perdere ore all'autore del post e risparmiare tempo a noi che leggiamo il suo prezioso post.

 

Share, share, share... lo metterei subito dopo lo slogan developer, developer, developer...

 

del.icio.us Tags: ,

 

 

Copyright © Luca Mauri