1 / 44

Things that should be Easy in SharePoint Development

Things that should be Easy in SharePoint Development. Eugene Rosenfeld CTO, Black Blade Associates. About me…. Eugene, MVP, MCAD, CTO Black Blade Associates http://www.blackbladeinc.com http://ThingsThatShouldBeEasy.blogspot.com ERosenfeld@BlackBladeInc.com

michi
Download Presentation

Things that should be Easy in SharePoint Development

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Things that should be Easy in SharePoint Development Eugene Rosenfeld CTO, Black Blade Associates

  2. About me… • Eugene, MVP, MCAD, CTO • Black Blade Associates • http://www.blackbladeinc.com • http://ThingsThatShouldBeEasy.blogspot.com • ERosenfeld@BlackBladeInc.com • Involved with distributed systems, SOA, peer-to-peer systems, and cloud computing. Applying these concepts to portals and document management.

  3. Intended Audience • 200-level session • Developers • Mid to senior level • Some SharePoint development experience

  4. Agenda • Querying Data • Workflow • User Interface • Platform

  5. Querying Data • Relational data queries • Date time queries • Site context via HTTP

  6. Relational Data Queries • Querying based on Lookup item Title is not reliable. • Workaround: • Query on the Item ID field • Specify LookupId or LookupValue attributes on FieldRef CAML element

  7. Relational Query Samples By Lookup ID By Lookup Value <Query><Where> <Eq> <FieldRef Name="CatalogItem" LookupValue="TRUE" /> <Value Type="Lookup">Value Goes Here</Value> </Eq> </Where> </Query> <Query><Where> <Eq> <FieldRef Name="CatalogItem" LookupId="TRUE" /> <Value Type="Lookup">1</Value> </Eq></Where> </Query>

  8. Date Time Queries • All date queries must be in UTC, but date updates must be in local time. • Date queries ignore time component. • Approach: • Create dates using the DateTimeKind.Utc enumeration or convert to Utc • Insert into CAML string using .ToString(“o”) • Specify the IncludeTimeValue on Value CAML element

  9. Date Time Query Sample <Where> <Geq> <FieldRef Name="Created" /> <Value Type="DateTime" IncludeTimeValue="TRUE">UTC_Date_Value</Value> </Geq> </Where>

  10. Site Context via HTTP • No easy way to get the Site and Web context given an arbitrary SharePoint Url • You need Web context to use SharePoint’s web services. • Workaround: • Use SharePoint’s Front Page HTTP RPC interface to map the Url to a Web Url. • Use the mapped Web Url for subsequent web service calls.

  11. This Windows forms application allows a user to select a local file and save it to an arbitrary Url in SharePoint, creating all necessary folders in the process. Save file to SharePoint from desktop app

  12. Workflow • Workflow tasks • Working with default task forms • Creating custom workflow activity components

  13. Creating Workflow Tasks • Creating a task requires code • Approach: • Handle CreateTask MethodInvoking event. • Set the TaskID, TaskProperties, TaskType, and CorrelationToken properties of CreateTask activity

  14. Processing Task Changes • Waiting for task complete requires binding multiple properties • Resolution: • Bind the TaskID, BerforeProperties, AfterProperties, and CorrelationToken properties of OnTaskUpdated activity • Check Status and Percent Complete AfterTaskProperties to see if task is complete

  15. Working with OOTB Task Forms • Referencing the correct content types and creating the task so it references the out of the box task form • Approach: • Element file: Set TaskListContentTypeId attribute, TaskN_FormUrn elements, and ExtendedStatusColumnValues element • TaskType property on CreateTask activity • Must set appropriate ExtendedProperties

  16. Elements File Sample <?xmlversion="1.0" encoding="utf-8" ?> <Elementsxmlns="http://schemas.microsoft.com/sharepoint/"> <Workflow Name=“My Workflow“ TaskListContentTypeId="0x01080100C9C9515DE4E24001905074F980F93160“ > <MetaData> <Task0_FormURN>urn:schemas-microsoft-com:office:infopath:workflow:ReviewRouting-Review:$Subst:LCID;</Task0_FormURN> <Task1_FormURN>urn:schemas-microsoft-com:office:infopath:workflow:ReviewRouting-Review:$Subst:LCID;</Task1_FormURN> <Task2_FormURN>urn:schemas-microsoft-com:office:infopath:workflow:ReviewRouting-Review:$Subst:LCID;</Task2_FormURN> <ExtendedStatusColumnValues> <StatusColumnValue>$Resources:ReviewFeedback_CanceledStatus</StatusColumnValue> <StatusColumnValue>$Resources:ReviewFeedback_ApprovedStatus</StatusColumnValue> <StatusColumnValue>$Resources:ReviewFeedback_RejectedStatus</StatusColumnValue> </ExtendedStatusColumnValues> </MetaData> </Workflow> </Elements>

  17. MethodInvoking Sample private void createTask1_MethodInvoking(object sender, EventArgs e) { //initialize task infrastructure data this.createTask1_TaskId1 = Guid.NewGuid(); this.createTask1_TaskProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties(); this.createTask1_TaskProperties1.TaskType = 1; //set task properties this.createTask1_TaskProperties1.Title = "New forms task for you..."; if (this.MaximumWaitTime.CompareTo(new TimeSpan(0, 0, 0)) > 0) this.createTask1_TaskProperties1.DueDate = DateTime.Now.Add(this.MaximumWaitTime); this.createTask1_TaskProperties1.Description = string.Format("Please review the form {0}/{1}.", this.WorkflowProperties.WebUrl, this.WorkflowProperties.ItemUrl); this.createTask1_TaskProperties1.ExtendedProperties["BodyText"] = this.createTask1_TaskProperties1.Description; this.createTask1_TaskProperties1.AssignedTo = this.AssignTaskTo; this.createTask1_TaskProperties1.SendEmailNotification = true; }

  18. Working with OOTB Task Forms • Handling task form activities: Approve, Reject, Request Change, Reassign • Approach: • All actions “completes” the task • Check the TaskStatus of the AfterTaskProperties ExtendedProperty of the OnTaskUpdated activity • “#”: Approved • “@”: Rejected

  19. Custom Workflow Components • Passing correlation tokens • Approach: • Create CorrelationToken property on custom activity • Set the TypeConverter attribute on the property to CorrelationTokenTypeConverter • When CorrelationToken property is set, set the CorrelationToken properties of all relevant child activities

  20. Sample CorrelationToken Prop public static DependencyProperty CorrelationTokenProperty = DependencyProperty.Register("CorrelationToken", typeof(CorrelationToken), typeof(MyActivity)); [DescriptionAttribute("Correlation Token"), CategoryAttribute(“My Category"), BrowsableAttribute(true), DefaultValue((string)null), TypeConverter("System.Workflow.Activities.CorrelationTokenTypeConverter, System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")] public CorrelationTokenCorrelationToken { get { return (CorrelationToken)base.GetValue(CorrelationTokenProperty); } set { base.SetValue(CorrelationTokenProperty, value); this.createTask1.CorrelationToken = value; this.waitForTaskCompletionActivity1.CorrelationToken = value; } }

  21. This workflow activity creates a workflow task using the out of the box SharePoint approval task form. The activity then waits for the user to approve or reject the task and reports the completion status to the parent workflow. Custom task activity

  22. User Interface • AJAX • Reusable dataview web parts • Web part connections

  23. AJAX • AJAX is easy. Integrating AJAX with ASP.Net post back model is harder. • AJAX Options • ASP.Net AJAX • Web Part Page Services (WPSC) • ECMAScript (New in SP 2010) • jQuery

  24. jQuery Approach • Use AdditionalPageHead feature to add JQuery library • Use component pages to return HTML / XML fragments to AJAX calls • Use hidden fields to persist state on post back without ViewState

  25. Reusable dataview web parts • Dataview web part stores references to List ID. Means it can’t be provisioned declaratively in Module feature. • Workaround: • Create a template text file with dataview contents as part of a feature. • Replace List ID with a token, like {%List_ID%} • Use a feature receiver to replace {%List_ID%} with actual List ID Guid

  26. This feature deploys a custom list to the web site and adds a dataview web part that provides data visualization for the list. Dataview web part feature

  27. Web part connections • Connecting to out of the box web parts • Lots of interfaces to implement • Needed interfaces are poorly documented • Interfaces to know: • ListView: IWebPartField, IWebPartRow, IWebPartTable • Filter: IFilterValues

  28. This web part is able to provide data to and consume data from many of the out of the box SharePoint web parts. Connector web part

  29. Platform • Platform Detection • Detection Mechanisms • Multi-platform Code

  30. Platform Detection • What are the platforms • WSS V2 / Portal Server 2003 • WSS V3 / Office SharePoint Server 2007 • SharePoint Foundation / SharePoint Server 2010 • Who should care • Product developers • SharePoint hosters • People supporting large deployments

  31. Detection Mechanisms – Object Model • Approach: Try to dynamically load the appropriate SharePoint assembly. Start by loading the higher version numbers first. • Example: • WSS V4 - Microsoft.SharePoint, 14.0.0.0 • WSS V3 - Microsoft.SharePoint, 12.0.0.0 • MSS 2010 - Microsoft.Office.Server, 14.0.0.0

  32. Detection Mechanisms - Registry • Approach: Query the registry for the desired platform key • Example: • MSS 2010 - HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14 • WSS 4 - HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0

  33. Detection Mechanisms - HTTP • Approach: Do an HTTP get for the WSDL of a service endpoint found only in the desired SharePoint platform. Get HTML or 404 = not the platform. • Example: • WSS V2: …_vti_bin/Lists.asmx • MOSS 2007: …_vti_bin/OfficialFile.asmx • WSS V4: …_vti_bin/Diagnostics.asmx • MSS 2010: …_vti_bin/SocialDataService.asmx

  34. Detection Mechanisms – File System • Approach: Check the version number(s) in the C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions folder • Example: • WSS V2: …\Web Server Extensions\60 • WSS V3: …\Web Server Extensions\12 • WSS V4: …\Web Server Extensions\14 • MSS 2010: …\14\Template\Features\MySite

  35. Multi-platform Code • Object model • HTTP code

  36. Multi-platform Object Model Code • Choice: Use late or early – bound code • Late bound • Don’t need access to each DLL version • No compiler support for error checks • Early bound • Need access to each DLL version • Full compiler support for error checks • Must be careful of where types are declared

  37. Early Bounding Sample private void button1_Click(object sender, System.EventArgs e) { System.Reflection.Assembly asmWSS; try { //try to load the assembly asmWSS = System.Reflection.Assembly.Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"); } catch(Exception ex) { //the assembly could not load. we assume there is no WSS on this computer asmWSS = null; } if(asmWSS != null) UseWSS(); } private void UseWSS() { //we have a strong reference to an SPSite object Microsoft.SharePoint.SPSite site = new Microsoft.SharePoint.SPSite("http://localhost"); MessageBox.Show(site.GetType().Name.ToString(), "SPSite object created"); }

  38. Late Binding Sample System.Reflection.Assembly asmWSS; try { asmWSS = System.Reflection.Assembly.Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"); } catch(Exception ex) { //the assembly could not load. we assume there is no WSS on this computer asmWSS = null; } if(asmWSS != null) { //get a late bound reference to the SPSite type //this is equivalent to SPSite objSPSite = new SPSite(“http://localhost”); Type typSPSite = asmWSS.GetType("Microsoft.SharePoint.SPSite"); //get a reference to the constructor for SPSite that has this signature: // new Microsoft.SharePoint.SPSite("http://localhost") // and invoke the constructor object objSPSite = typSPSite.GetConstructor(new Type[]{ typeof(string) }).Invoke(new object[]{ "http://localhost" }); }

  39. Multi-platform HTTP Code • Detect which version of SharePoint a remote endpoint is running • You will need the WSDL of each service version you want to invoke • Instantiate the appropriate service proxy after the platform detection

  40. Web Service Sample AreaWS.AreaData adArea; try { // get the area information for the web id adArea = areaWS.GetAreaData(new Guid(sWebMetadata.WebID)); } catch { // we were unable to execute the area service. assume WSS only MessageBox.Show(this.txtURL.Text + " is a site. The server has WSS, not SPS."); return; } if(adArea.WebUrl == null) // a null web url means the web id does not correspond to an area MessageBox.Show(this.txtURL.Text + " is a site. The server has both WSS and SPS"); else // a valid web url means the web id does correspond to an area MessageBox.Show(this.txtURL.Text + " is an area.");

  41. This web part can run on both versions of SharePoint 2010 and take advantage of the features of each platform. Multi-platform web part

  42. Additional Resources • Workflow • Serge Luca: http://sergeluca.spaces.live.com/blog/cns!E8A06D5F2F585013!859.entry • Eugene Rosenfeld:http://thingsthatshouldbeeasy.blogspot.com/2010/03/how-to-use-default-sharepoint.html • AJAX – Jan Tielens • http://www.bing.com/search?q=site%3Ahttp%3A%2F%2Fweblogs.asp.net+jan+sharepoint+jquery

  43. Additional Resources • Relational Data Queries – MSDN • http://msdn.microsoft.com/en-us/library/ms442728.aspx • Multi-platform Code – Black Blade • http://www.blackbladeinc.com/en-us/community/Pages/Speaking.aspx

  44. Thank you for attending! Eugene Rosenfeld ERosenfeld@BlackBladeInc.com http://ThingsThatShouldBeEasy.blogspot.com

More Related