Comments
Description
Transcript
Sviluppare Web Part
Windows SharePoint 2003 Products & Technologies – Sviluppare Web Part Marco Bellinaso Senior trainer & consultant Code Architects S.r.l. Web: http://www.codearchitects.com E-mail: [email protected] 1 Biografia Consulenza, sviluppo e training con Code Architects Srl Collaboratore di Visual Basic & .NET Journal, Computer Programming, MSDN Magazine e ASP Today Coautore di “ASP.NET Website Programming”, “Fast Track ASP.NET” e “Visual C# .NET: a Guide for VB6 Developers” (Wrox Press) Sviluppatore di UGI SharePoint (www.ugisharepoint.it) Sviluppatore dei siti *2TheMax (www.dotnet2themax.com) (www.dotnet2themax.it ) e-mail: [email protected] http://www.codearchitects.com 2 Agenda Concetti base Generazione manuale di HTML Riutilizzo di controlli ASP.NET Proprietà Deployment Debug Web part avanzate Custom Tool Part Connessioni http://www.codearchitects.com 3 Architettura ASP.NET Page Controlli ASP.NET che ereditano dalla classe base WebPart, che a sua volta eredita da System.Web.UI.Control Web Part zone Le Web Part sono controlli ASP.NET server-side che vengono inseriti all’interno di pagine o zone eseguite nel contesto di SharePoint Forniscono caratteristiche comuni, offerte dal framework Titolo, bordi, stato (minimizzato ecc.) Supporto per drag & drop Proprietà shared o per utente I controlli sulla pagina sono determinati da record del DB dei contenuti Implementano interfacce standard per comunicare le une con le altre http://www.codearchitects.com 4 Sviluppo in VS.NET Microsoft fornisce un template per VS.NET 2003, scaricabile separatamente, chiamato “Web Part Library” http://www.codearchitects.com WebPart1.cs: scheletro per la classe della Web Part WebPart1.dwp: file XML che descrive la Web Part (nome, descrizione) e contiene valori di default per alcune proprietà AssemblyInfo.cs: specifica versione, il file .snk per lo strong name, ecc. Manifest.xml: file XML che contiene un riferimento a tutti i file necessari “References” contiene un riferimento a Microsoft.SharePoint dll 5 Classe base Browser Rendering Non è possibile fare l’override del metodo Render() della classe base La classe base lo usa per creare il bordo, il titolo e il menu della Web Part Le Web Part custom devono implementare l’override di RenderWebPart() per fare l’output dell’HTML del proprio contenuto http://www.codearchitects.com 6 Classe base Browser Rendering ASP.NET starts page render Request ASPX Page Web Part WebPart.Render() Response http://www.codearchitects.com CustomPart.RenderWebPart() 7 Classe base Rendering per client diversi da browser L’interfaccia IDesignTimeHtmlProvider viene usata per ottenere il rendering della Web Part quando questa viene inserita in client diversi dal browser Internet. Es: FrontPage 2003 IDesignTimeHtmlProvider consiste in un singolo metodo: GetDesignTimeHtml Non è implementata di default http://www.codearchitects.com 8 Classe base Override di eventi I seguenti metodi della classe base sono marcati come sealed, e non se ne può fare l’override: OnInit , OnDataBinding, OnLoad, OnPreRender, OnUnload Ci si può iscrivere agli eventi relativi: this.Load += new EventHandler (myLoadEvent); http://www.codearchitects.com 9 Proprietà Introduzione Le Web Part, come gli altri controlli web, possono esporre proprietà custom che permettono di personalizzarne il comportamento e l’aspetto Due tipi di proprietà: Proprietà della classe base Proprietà custom Tutte le proprietà devono poter essere serializzabili tramite l’XmlSerializer Gli attributi della proprietà ne possono cambiare il comportamento http://www.codearchitects.com 10 Proprietà Attributi supportati Browsable (.Net) Category (.Net) Description (.Net) - Ecc. – FriendlyName (Web Part Framework) HtmlDesigner (Web Part Framework) WebPartStorage (Web Part Framework) - Ecc. - http://www.codearchitects.com 11 Proprietà Modifica e salvataggio dei valori delle proprietà Le proprietà vengono serializzate e salvate nel database Due contesti di salvataggio Il tipo di storage è controllato dall’attributo WebPartStorage: Shared Personal WebPartStorage = Storage.Shared WebPartStorage = Storage.Personal WebPartStorage = Storage.None I valori di default delle proprietà possono anche essere salvati nel file .dwp <WebPart> ... <Text xmlns=”MyWebPart”>Hello World!</Text> </WebPart> http://www.codearchitects.com 12 Proprietà [Browsable(true), Category("Miscellaneous"), DefaultValue(defaultText), WebPartStorage(Storage.Personal), FriendlyName("Text"),Description("Text Property")] public string Text { get { return _text; } set { _text = value; } } protected override void RenderWebPart(HtmlTextWriter output) { output.Write(SPEncode.HtmlEncode(this.Text)); } http://www.codearchitects.com 13 Rendering Due metodi per eseguire il rendering Il codice HTML viene generato tutto manualmente, all’interno di RenderWebPart Creare dei controlli ASP.NET all’interno di CreateChildControls, ed eseguirne il rendering in RenderWebPart Pro: controllo totale sul codice generato Contro: codifica molto lunga, non si sfruttano alcuni dei vantaggi più interessanti di ASP.NET Pro: La generazione di output complesso (es: griglie) è incapsulata all’interno delle classi di .NET Pro: Si possono sfruttare eventi Contro: in alcuni casi personalizzazioni avanzate richiedono più sforzo di una completa codifica manuale Soluzione ideale: scrivere Web Part sotto forma di user control, ma...gli user control non sono attualmente supportati! http://www.codearchitects.com 14 Rendering di controlli ASP.NET protected override void CreateChildControls() { btnSubmit = new Button(); btnSubmit.Text = "Somma"; btnSubmit.Click += new EventHandler(btnSubmit_Click); this.Controls.Add(btnSubmit); txtOp1 = new TextBox(); this.Controls.Add(txtOp1); txtOp2 = new TextBox(); this.Controls.Add(txtOp2); lblResult = new Label(); this.Controls.Add(lblResult); } public void btnSubmit_Click(object sender, EventArgs e) { lblResult.Text = "La somma è " + (Convert.ToInt32(txtOp1.Text)+Convert.ToInt32(txtOp2.Text)).ToString(); } protected override void RenderWebPart(HtmlTextWriter output) { output.Write("Operando 1: "); txtOp1.RenderControl(output); output.Write("Operando 2: "); txtOp2.RenderControl(output); btnSubmit.RenderControl(output); lblResult.RenderControl(output); } http://www.codearchitects.com 15 Deployment Deployment manuale 1) 2) 3) 4) Compilazione con strong name (opzionale) Copia dell’assembly nel folder /bin Registrazione come “safe control” Preparazione e copia/importazione del file .dwp Deployment “semi-automatico” 1) 2) 3) 4) 5) Compilazione con strong name (opzionale) Preparazione del file .dwp Preparazione di un file manifest.xml Preparazione di un pacchetto .cab Installazione del pacchetto .cab con stsadm.exe http://www.codearchitects.com 16 Deployment manuale Compilare un assembly con strong name significa dargli un nome univoco, per versioni diverse. Assembly con lo stesso nome possono coesistere senza essere rinominati Creare un file con le chiavi pubblica/privata sn.exe - k c:\keypair.snk Modificare AssemblyInfo.cs, impostando gli attributi AssemblyVersion e AssemblyKeyFile [assembly: AssemblyKeyFile(@"c:\keypair.snk")] [assembly: AssemblyVersion("1.0.0.0")] http://www.codearchitects.com 17 Deployment manuale Registrazione come safe control Aggiungere una nuova entry all’interno di <SafeControls> in web.config (senza “a capo”) <SafeControl Assembly="WebCalcWebPart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e0cc4e02e14341c1" Namespace="WebCalcWebPart“ TypeName="*" Safe="True" /> Il file .dwp di descrizione <?xml version="1.0" encoding="utf-8"?> <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2" > <Title>WebCalc</Title> <Description>Impressive beb-based calculator</Description> <Assembly>WebCalcWebPart</Assembly> <TypeName>WebCalcWebPart.WebCalc</TypeName> <!– Valori di default per proprietà... --> </WebPart> http://www.codearchitects.com 18 Deployment con stsadm.exe Stsadm.exe può installare una o più Web Part presenti all’interno di un pacchetto .cab. Si occupa di: Copiare gli assembly in /bin Copia i file .dwp di descrizione in /wpcatalog Copia eventuali file di risorse in /wpresources Registra le Web Part come safe control Copiare il file .cab all’interno del database di configurazione http://www.codearchitects.com 19 Deployment con stsadm.exe Stsadm.exe installa un pacchetto .cab che deve contenere: Gli assembly .dll I file .dwp di descrizione Eventuali file di risorse Un file manifest.xml che elenca tutti i file Il pacchetto .cab può essere creato da VS.NET Setup & Deployment Projects \ CAB Project Basta includere “Primary Output” e “Content Files” Stsadm.exe –o addwppack –filename path_to_webpart.cab Opzione –globalInstall: installa gli assembly nella GAC pieni permessi di esecuzione -> deployment facilitato, ma meno sicuro Opzione –force: sovrascrive la Web Part, se già presente http://www.codearchitects.com 20 Deployment Contenuto del file manifest.xml file <?xml version="1.0"?> <WebPartManifest xmlns="http://schemas.microsoft.com/WebPart/v2/Manifest"> <Assemblies> <Assembly FileName="WebCalcWebPart.dll"> <ClassResources> <ClassResource FileName="Resource.jpg"/> </ClassResources> <SafeControls> <SafeControl Namespace="WebCalcWebPart" TypeName="*" /> </SafeControls> </Assembly> </Assemblies> <DwpFiles> <DwpFile FileName="WebCalc.dwp"/> </DwpFiles> </WebPartManifest> http://www.codearchitects.com 21 Debugging Apportare delle modifiche a web.config debug="true" in <compilation> mode="RemoteOnly" o mode="Off" in <customErrors> CallStack="true" nel tag <SafeMode> Eseguire il debug di una Web Part: 1) 2) 3) 4) Compilare, registrare e importare la Web Part in una pagina (può essere richiesto un riavvio di IIS – iisreset) Impostare i breakpoint Da VS.NET selezionare “Tools / Debug Processes...” oppure “Debug / Processes...” e selezionare “w3wp.exe” Se w3wp.exe non è elencato, assicurarsi che l’opzione “Show system processes” sia selezionata, e caricare una pagina del browser per assicurarsi che il processo parta Caricare la pagina nel browser...l’esecuzione si fermerà al breakpoint http://www.codearchitects.com 22 Risorse SmartPart Web part che permette di “hostare” User Control Permette di scrivere Web Part in modo molto più immediato, riutilizzando controlli già pronti Gli user control possono essere testati all’interno di una normale pagina ASP.NET, prima di essere aggiunti ad una pagina di SharePoint Debug molto semplificato Permette allo user control referenziato di esporre proprietà e di supportare connessioni, mediante implementazione di sue interfacce http://www.smartpart.info http://www.codearchitects.com 23 Risorse STSAdmWin (Microsoft) Interfaccia grafica per stsadm.exe Bastato file file .xml di definizioni dei comandi Facilmente estendibile, se necessario http://download.microsoft.com/download/1/6/8/16 887e30-897e-4d6c-afce3e85a43e6eaa/stsadmWin-2go.zip http://www.codearchitects.com 24 Risorse WPPackager (Microsoft) Crea un pacchetto .msi autoinstallante L’utente può scegliere se installare la Web Part nella GAC Disinstallazione standard Può creare nuovi permission-set (utile se il pacchetto non viene installato nella GAC) Necessita di: Il file manifest.xml, e tutti gli altri file della libreria Un “packaging file”, che indica proprietà del file MSI risultante, politiche di sicurezza, e il nome del manifest da includere http://www.microsoft.com/downloads/details.aspx? FamilyId=0FDA5912-C136-4B44-911A011ADFCC66E3&displaylang=en http://www.codearchitects.com 25 Tool Part Introduzione Sono anch’essi controlli web, usati per aggiungere funzionalità al tool pane standard Diverse dalle Web Part Non possono essere spostate Poche proprietà nella classe base Non c’è supporto per lo storage di proprietà Rendering solo all’interno del tool pane Il processo di rendering è simile a quello delle Web Part Non si può fare l’override di ToolPart.Render() Bisogna fare l’override di ToolPart.RenderToolPart() http://www.codearchitects.com 26 Tool Part Metodi importanti ToolPart.ApplyChanges() ToolPart.CancelChanges() Chiamato quando l’utente clicca Cancel dalla pagina delle proprietà ToolPart.SyncChanges() Chiamato quando l’utente clicca Apply / Ok dalla pagina delle proprietà Chiamato quando serve un refresh della toolpart (ad es. quando un’altra toolpart salva le sue proprietà) WebPart.GetToolParts() Metodo della Web Part base, usato per associare le toolpart della Web Part http://www.codearchitects.com 27 ToolPart – RenderToolPart() protected override void RenderToolPart(HtmlTextWriter output) { //get a reference to the parent Web Part SpecialSayHello parentWebPart = (SpecialSayHello) this.ParentToolPane.SelectedWebPart; //print the text box HTML output.Write("Enter your age: "); output.Write("<input name='" + inputName); output.Write("' type='text' value='" + SPEncode.HtmlEncode(parentWebPart.Age) + "'>"); } public override void ApplyChanges() { //get a reference to the parent Web Part SpecialSayHello parentWebPart = (SpecialSayHello) this.ParentToolPane.SelectedWebPart; //set the Age property of the parent Web Part based on Form Input parentWebPart.Age = Page.Request.Form[inputName]; } http://www.codearchitects.com 28 ToolPart – GetToolParts() public override ToolPart[] GetToolParts() { //the array that holds instances of all ToolParts ToolPart[] toolparts = new ToolPart[3]; //standard toolparts creation WebPartToolPart wptp = new WebPartToolPart(); CustomPropertyToolPart custom = new CustomPropertyToolPart(); //the toolpart that we are adding creation AgeDisplayerToolPart ad = new AgeDisplayerToolPart(); toolparts[0] = wptp; toolparts[1] = custom; toolparts[2] = ad; return toolparts; } http://www.codearchitects.com 29 Connessioni Le connessioni permettono a Web Part separate (ed indipendenti) di scambiarsi dati di tipo base: Cell, Row, List ecc. Implementazione di un set di interfacce standard Due Web Part possono essere collegate da browser o FrontPage http://www.codearchitects.com 30 Connessioni – Scenari Parent / Child Master / Detail Data entry and filtering http://www.codearchitects.com 31 Connessioni – Interfacce ICellProvider, ICellConsumer IRowProvider, IRowConsumer IListProvider, IListConsumer IFilterProvider, IFilterConsumer IParametersOutProvider, IParametersOutConsumer IParametersInProvider, IParametersInConsumer http://www.codearchitects.com 32 Connessioni – Cell Consumer/Provider diagram Web Part Framework ICellProvider ICellConsumer Events CellProviderInit() CellReady() Events CellConsumerInit() Event Handlers CellProviderInit() CellReady() Event Handlers CellConsumerInit() http://www.codearchitects.com 33 Connessioni – Codice EnsureInterfaces() RegisterInterface() CanRunAt() PartCommunicationConnect() PartCommunicationInit() Solleva eventi Init (Es. CellProviderInit) PartCommunicationMain() Solleva gli eventi rimanenti (Es. CellReady) http://www.codearchitects.com 34 Connessioni – Codice 1) Creare la classe che implementa le interfacce public class CellProvider : WebPart, ICellProvider { // ... } 2) Dichiarare gli eventi // CellProviderInit Event – // provides the field name and display field name to the consumer Web Part public event CellProviderInitEventHandler CellProviderInit; // CellReady Event - occurs whenever a cell is selected or updated public event CellReadyEventHandler CellReady; http://www.codearchitects.com 35 Connessioni – Codice 3) Fare l’override del metodo EnsureInterfaces, e al suo interno chiamare RegisterInterface public override void EnsureInterfaces() { RegisterInterface("MyCellProviderInterface_WPQ_", "ICellProvider", WebPart.UnlimitedConnections, ConnectionRunAt.ServerAndClient, this, "CellProviderInterface_WPQ_", "Fornisce singolo valore a...", "Fornisce ad un’altra Web Part il valore inserito nella textbox" ); } 4) Fare l’override del metodo CanRunAt public override ConnectionRunAt CanRunAt() { return ConnectionRunAt.ServerAndClient; } http://www.codearchitects.com 36 Connessioni – Codice 5) Fare l’override di PartCommunicationConnect Notifica la Web Part che è stata creata una connessione public override void PartCommunicationConnect( string interfaceName, WebPart connectedPart, string connectedInterfaceName, ConnectionRunAt runAt) { if (runAt == ConnectionRunAt.Client) { _runAtClient = true; return; } EnsureChildControls(); // create the Web Part's controls // Check if this is my particular cell interface if (interfaceName == "MyCellProviderInterface_WPQ_") _cellConnectedCount++; // count connections } http://www.codearchitects.com 37 Connessioni – Codice 6) Opzionale: override del metodo PartCommunicationInit, responsabile del sollevamento degli eventi di inizializzazione public override void PartCommunicationInit() { if(_cellConnectedCount > 0) { if (CellProviderInit != null) { CellProviderInitEventArgs args = new CellProviderInitEventArgs(); args.FieldName = _cellName; args.FieldDisplayName = _cellDisplayName; CellProviderInit(this, args); } } } http://www.codearchitects.com 38 Connessioni – Codice 7) Opzionale: override del metodo PartCommunicationMain, responsabile del sollevamento degli altri eventi (es: CellReady) public override void PartCommunicationMain() { if (_cellConnectedCount > 0) { if (CellReady != null) { CellReadyEventArgs args = new CellReadyEventArgs(); args.Cell = this.ctlInputBox.Text; CellReady(this, args); } } } http://www.codearchitects.com 39 Connessioni – Codice 8) Implementare gli appropriati gestori di evento, a seconda del tipo di interfaccia che si sta implementando public void CellConsumerInit(object sender, CellConsumerInitEventArgs cellConsumerInitEventArgs) { // This is where the Provider part could see what type of "Cell" // the Consumer was expecting/requesting. } http://www.codearchitects.com 40 Connessioni – Codice 9) Fare l’override del metodo CreateChildControls protected override void CreateChildControls() { // crea il bottone di submit e registra il suo evento Click ctlSubmitButton = new Button(); ctlSubmitButton.ID = “SubmitButton"; ctlSubmitButton.Text = “Submit"; this.Controls.Add(ctlSubmitButton); ctlSubmitButton.Click += new EventHandler(SubmitButtonClicked); // crea il controllo textBox ctlInputBox = new TextBox(); ctlInputBox.ID = “InputBox"; this.Controls.Add(ctlInputBox); cellName = “InputBox"; cellDisplayName = "InputBox Cell"; } http://www.codearchitects.com 41 Connessioni – Codice 10) Fare l’override del metodo RenderWebPart protected override void RenderWebPart(HtmlTextWriter output) { EnsureChildControls(); if (_runAtClient) { // Render client connection code if needed } else { if (_cellConnectedCount > 0) { this.ctlInputBox.RenderControl(output); this.ctlSubmitButton.RenderControl(output); } else output.Write(“No connection is set-up."); } } http://www.codearchitects.com 42 Estendere il framework Property Builder Pagine web (.htm) caricate all’interno di dialog del browser Collegato alle proprietà che ne vogliono fare uso tramite attributo HtmlDesignerAttribute Es: Color picker; picture picker, file picker, date picker (questi sono già implementati, e disponibili tramite costanti del tipo BrowserBuilderType.*) http://www.codearchitects.com 43 Estendere il framework Menu della Web Part Possibilità di aggiungere voci custom al context menu delle proprie Web Part Override del metodo CreateWebPartMenu() Si possono aggiungere elementi MenuItem alla collezione WebPartMenu.MenuItems, associandovi del codice javascript client-side, e un gestore di evento server-side Si possono referenziare le voci di menu built-in, per nasconderle, disabilitarle, cambiarle di posizione, o associarvi un comportamento diverso http://www.codearchitects.com 44 Il futuro ASP.NET 2.0 include il supporto per Web Part Possibilità di scrivere Web Part come User Control! Supporto per le Web Part per SharePoint già esistenti La prossima versione di SharePoint sarà basata su ASP.NET 2.0 e potrà sfruttare i vantaggi delle sue Web Part Microsoft intende rilasciare un aggiornamento per SharePoint che consenta il supporto delle Web Part di ASP.NET 2.0 prima di SharePoint 3.0 http://www.codearchitects.com 45 Domande? http://www.ugisharepoint.it http://www.dotnet2themax.it/blog http://www.codearchitects.com 46