SlideShare a Scribd company logo
Advanced SharePoint Web Part Development
Rob Windsor
rob@robwindsor.com
@robwindsor
About Me
 Senior SharePoint Consultant
 Technical Contributor to the Pluralsight On-Demand Library
 Microsoft MVP, MCPD, MCT
 Founder and Past-President of the North Toronto .NET UG
 Co-author of Prof. Visual Basic 2012 and .NET 4.5 (Wrox)
Session Prerequisites
 Experience developing for SharePoint
 Experience building Web Parts
 Experience with JavaScript and jQuery
Agenda
 Script Parts
 Persistent Web Part Properties
 Editor Parts
 Script Part Properties
 Connectable Web Parts
 Asynchronous Web Parts
 Web Part Gallery
 Web Part Pages
DEMO
Basic Web Parts
Script Parts
 Web parts implemented using only JavaScript
 Why?
 Can’t deploy farm solutions to SharePoint Online
 Sandbox solutions with managed code are deprecated
 Restrictions
 Can’t create custom web parts without managed code
 Must use OOB web parts to implement script parts
 Implementation
 Use modules to provision JavaScript/HTML files
 Use custom actions to load common JavaScript files
 Use Content Editor Web Part to inject HTML and JavaScript into page
DEMO
Script Part
Web Part Properties
 Web Parts support persistent properties
 Configure properties via attributes
 Personalizable(param)
 Directs SharePoint to persist property value
 Parameter indicates if property may be personalized
 WebBrowsable(true)
 Directs SharePoint to generate interface to edit property
 WebDisplayName, WebDescription
 The prompt and tooltip that accompany the data entry element
 Category
 The group in which the properties will be shown
[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(true)]
[WebDisplayName("Year")]
[Category("Pluralsight")]
public int Year { get; set; }
DEMO
Web Part Properties
Editor Parts
 Editor parts enable user customization
 Editor parts contained within an editor
zone
 ASP.NET supplies standard editor parts
 Layout, appearance, etc
 Developers can create custom editor
parts
 Similar development experience to Web Part
 Control over interface used to edit properties
 Ability to validate user input
 In web part
 Override CreateEditorParts
 In editor part
 Override CreateChildControls, SyncChanges and
ApplyChanges
DEMO
Editor Parts
Script Part Properties
 No way to implement real web part properties without managed code
 We can emulate the user experience
 Property values stored in element attribute
 Detect when property editor is open
 Add data entry controls into editor using jQuery
 Capture submit event and retrieve values
 Update attribute containing property values
 Use native script editor web part persistence mechanism
 Alternative implementation
 Build Custom Web Part Properties with JSOM
 vxcompany.com/kennis/blog/2014/10/02/build-custom-web-part-properties-jsom/
DEMO
Script Part Properties
IMPORTANT: This demo is a
proof of concept only. It is
nowhere near production
ready!
Creating Connectable Web Parts
 Pass data from one web part to another
 Loosely-coupled connection
 Communication managed by WebPartManager
 Provider web part supplies data
 Consumer web parts retrieve data
 Interface used to define data contract
 ASP.NET has standard connection contracts
 Shown later in this module
 Can use custom connection contracts
 SharePoint provides user interface elements to establish
connections
 Not compatible with sandboxed solutions
DEMO
Web Part Connections
Web Part Connections using Ajax
 Communication between web parts requires a postback
 Generally, only consumer web part needs to be updated
 Can use partial page rendering (UpdatePanel) to only update
consumer
 Problem:
 Event triggered by provider
 UpdatePanel in consumer
 Solution:
 Pass reference to control that triggers update from provider to consumer
 Consumer registers control as AsyncPostbackControl with
ScriptManager
DEMO
Web Part Connections
Using Ajax
Asynchronous Loading of Web Parts
 Long running tasks are blocking calls
 One web part can bring a page to a crawl
 When on the same page, multiple instances can kill the user experience
 Make long running tasks asynchronous
 Don’t hold up page processing
Asynchronous Loading of Web Parts
protected void Page_PreRender(object sender, EventArgs e) {
_func = new Func<XDocument>(GetFeed);
Page.RegisterAsyncTask(
new PageAsyncTask(
new BeginEventHandler(BeginFeed),
new EndEventHandler(EndFeed),
new EndEventHandler(TimoutFeed),
null, true));
}
public IAsyncResult BeginFeed(object sender, EventArgs e, AsyncCallback cb, object state) {
return _func.BeginInvoke(cb, state);
}
public void EndFeed(IAsyncResult ar) {
var feed = _func.EndInvoke(ar);
var posts = from item in feed.Descendants("item")
select new {
Title = item.Element("title").Value,
Description = item.Element("description").Value,
Published = DateTime.Parse(item.Element("pubDate").Value)
};
posts = posts.Skip(_pageNum * PageSize).Take(PageSize);
FeedListView.DataSource = posts.ToList();
FeedListView.DataBind();
}
DEMO
Async Loading of Web
Parts
Minimal Download Strategy
 All controls on a page must be marked as MdsCompliant for
page to use Minimal Download Strategy
 MdsCompliant Restrictions:
 HTML style and script tags are not supported
 Use CssRegistration and ScriptLink instead
 Using Response object to write to page is not supported
 Use SPHttpUtility.Write* instead
 Inline code must be wrapped in SharePoint:ScriptBlock element
 For more information see Modify SharePoint components for MDS
 http://msdn.microsoft.com/library/office/dn456543.aspx
DEMO
MdsCompliant
Cleaning the Web Part Gallery
 Files provisioned into Content DB do not get removed on
Feature deactivation
 This includes webpart / dwp files added to Web Part Gallery
 Deletion of files can be done in Feature receiver
 Examine element manifests to find web parts
 Remove from web part gallery
Cleaning the Web Part Gallery
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
var site = properties.Feature.Parent as SPSite;
if (site == null) return;
var parts = new List<string>();
var elements = properties.Definition.GetElementDefinitions(CultureInfo.CurrentCulture);
foreach (SPElementDefinition element in elements) {
if (element.ElementType != "Module") continue;
var node = element.XmlDefinition;
if (node.Attributes["Url"].Value != "_catalogs/wp") continue;
foreach (XmlElement childNode in node.ChildNodes) {
if (childNode.Name == "File") {
parts.Add(childNode.GetAttribute("Url"));
}
}
}
var web = site.RootWeb;
var gallery = web.Lists["Web Part Gallery"];
var items = gallery.Items;
for (int i = items.Count - 1; i >= 0; i--) {
var item = items[i];
if (parts.Contains(item.File.Name)) {
item.Delete();
}
}
}
DEMO
Cleaning the Web Part
Gallery
Creating Web Part Page Templates
 Create a site page
 Set base type to
Microsoft.SharePoint.WebPartPages.WebPartPage
 Add one or more web part zones to page
 Provision page instances using Module
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>

<%@ Register Tagprefix="WebPartPages"
Namespace="Microsoft.SharePoint.WebPartPages"
Assembly="Microsoft.SharePoint, Version=14.0.0.0, …" %>
<%@ Page Language="C#"
Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage"
MasterPageFile="~masterurl/default.master" %>
<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
<WebPartPages:WebPartZone
ID="MainZone" runat="server"
FrameType="TitleBarOnly"
Title="Main Web Part Zone" />
</asp:Content>
Adding Web Parts to Web Part Pages
 Use SPLimitedWebPartManager
 Get reference from property of Page object
 Use SPLimitedWebPartManager.AddWebPart to add
var page = web.GetFile("SiteAssets/Test02.aspx");
using (var manager = page.GetLimitedWebPartManager(
PersonalizationScope.Shared)) {
if (!manager.WebParts.Contains(webPartTitle))
{
var part = new MostPopularProducts2.MostPopularProducts2();
part.Title = "Most Popular Products";
part.Category = "Condiments";
part.Year = 1997;
manager.AddWebPart(part, "Left", 0);
}
}
Note: Contains method shown in code sample is a custom extension
DEMO
Creating Web Part Pages
and Adding Web Parts
Additional Stuff
 Closing versus deleting web parts
 Closing a web part does not remove it from page
 Having many closed web parts on a page can degrade performance
 Set AllowClose to false to remove option to close from web part verbs
 Versioning
 DO NOT change the assembly version of your assemblies
 SharePoint stores the full name with version of all web parts in galleries
and on pages
 Use the AssemblyFileVersion instead
Thank You
 Big thanks to the organizers, sponsors and you for
making this event possible
 Please fill out your evaluation
 Please keep in touch
rob@robwindsor.com
@robwindsor
msmvps.com/blogs/windsor

More Related Content

Advanced SharePoint Web Part Development

  • 1. Advanced SharePoint Web Part Development Rob Windsor rob@robwindsor.com @robwindsor
  • 2. About Me  Senior SharePoint Consultant  Technical Contributor to the Pluralsight On-Demand Library  Microsoft MVP, MCPD, MCT  Founder and Past-President of the North Toronto .NET UG  Co-author of Prof. Visual Basic 2012 and .NET 4.5 (Wrox)
  • 3. Session Prerequisites  Experience developing for SharePoint  Experience building Web Parts  Experience with JavaScript and jQuery
  • 4. Agenda  Script Parts  Persistent Web Part Properties  Editor Parts  Script Part Properties  Connectable Web Parts  Asynchronous Web Parts  Web Part Gallery  Web Part Pages
  • 6. Script Parts  Web parts implemented using only JavaScript  Why?  Can’t deploy farm solutions to SharePoint Online  Sandbox solutions with managed code are deprecated  Restrictions  Can’t create custom web parts without managed code  Must use OOB web parts to implement script parts  Implementation  Use modules to provision JavaScript/HTML files  Use custom actions to load common JavaScript files  Use Content Editor Web Part to inject HTML and JavaScript into page
  • 8. Web Part Properties  Web Parts support persistent properties  Configure properties via attributes  Personalizable(param)  Directs SharePoint to persist property value  Parameter indicates if property may be personalized  WebBrowsable(true)  Directs SharePoint to generate interface to edit property  WebDisplayName, WebDescription  The prompt and tooltip that accompany the data entry element  Category  The group in which the properties will be shown [Personalizable(PersonalizationScope.Shared)] [WebBrowsable(true)] [WebDisplayName("Year")] [Category("Pluralsight")] public int Year { get; set; }
  • 10. Editor Parts  Editor parts enable user customization  Editor parts contained within an editor zone  ASP.NET supplies standard editor parts  Layout, appearance, etc  Developers can create custom editor parts  Similar development experience to Web Part  Control over interface used to edit properties  Ability to validate user input  In web part  Override CreateEditorParts  In editor part  Override CreateChildControls, SyncChanges and ApplyChanges
  • 12. Script Part Properties  No way to implement real web part properties without managed code  We can emulate the user experience  Property values stored in element attribute  Detect when property editor is open  Add data entry controls into editor using jQuery  Capture submit event and retrieve values  Update attribute containing property values  Use native script editor web part persistence mechanism  Alternative implementation  Build Custom Web Part Properties with JSOM  vxcompany.com/kennis/blog/2014/10/02/build-custom-web-part-properties-jsom/
  • 13. DEMO Script Part Properties IMPORTANT: This demo is a proof of concept only. It is nowhere near production ready!
  • 14. Creating Connectable Web Parts  Pass data from one web part to another  Loosely-coupled connection  Communication managed by WebPartManager  Provider web part supplies data  Consumer web parts retrieve data  Interface used to define data contract  ASP.NET has standard connection contracts  Shown later in this module  Can use custom connection contracts  SharePoint provides user interface elements to establish connections  Not compatible with sandboxed solutions
  • 16. Web Part Connections using Ajax  Communication between web parts requires a postback  Generally, only consumer web part needs to be updated  Can use partial page rendering (UpdatePanel) to only update consumer  Problem:  Event triggered by provider  UpdatePanel in consumer  Solution:  Pass reference to control that triggers update from provider to consumer  Consumer registers control as AsyncPostbackControl with ScriptManager
  • 18. Asynchronous Loading of Web Parts  Long running tasks are blocking calls  One web part can bring a page to a crawl  When on the same page, multiple instances can kill the user experience  Make long running tasks asynchronous  Don’t hold up page processing
  • 19. Asynchronous Loading of Web Parts protected void Page_PreRender(object sender, EventArgs e) { _func = new Func<XDocument>(GetFeed); Page.RegisterAsyncTask( new PageAsyncTask( new BeginEventHandler(BeginFeed), new EndEventHandler(EndFeed), new EndEventHandler(TimoutFeed), null, true)); } public IAsyncResult BeginFeed(object sender, EventArgs e, AsyncCallback cb, object state) { return _func.BeginInvoke(cb, state); } public void EndFeed(IAsyncResult ar) { var feed = _func.EndInvoke(ar); var posts = from item in feed.Descendants("item") select new { Title = item.Element("title").Value, Description = item.Element("description").Value, Published = DateTime.Parse(item.Element("pubDate").Value) }; posts = posts.Skip(_pageNum * PageSize).Take(PageSize); FeedListView.DataSource = posts.ToList(); FeedListView.DataBind(); }
  • 21. Minimal Download Strategy  All controls on a page must be marked as MdsCompliant for page to use Minimal Download Strategy  MdsCompliant Restrictions:  HTML style and script tags are not supported  Use CssRegistration and ScriptLink instead  Using Response object to write to page is not supported  Use SPHttpUtility.Write* instead  Inline code must be wrapped in SharePoint:ScriptBlock element  For more information see Modify SharePoint components for MDS  http://msdn.microsoft.com/library/office/dn456543.aspx
  • 23. Cleaning the Web Part Gallery  Files provisioned into Content DB do not get removed on Feature deactivation  This includes webpart / dwp files added to Web Part Gallery  Deletion of files can be done in Feature receiver  Examine element manifests to find web parts  Remove from web part gallery
  • 24. Cleaning the Web Part Gallery public override void FeatureDeactivating(SPFeatureReceiverProperties properties) { var site = properties.Feature.Parent as SPSite; if (site == null) return; var parts = new List<string>(); var elements = properties.Definition.GetElementDefinitions(CultureInfo.CurrentCulture); foreach (SPElementDefinition element in elements) { if (element.ElementType != "Module") continue; var node = element.XmlDefinition; if (node.Attributes["Url"].Value != "_catalogs/wp") continue; foreach (XmlElement childNode in node.ChildNodes) { if (childNode.Name == "File") { parts.Add(childNode.GetAttribute("Url")); } } } var web = site.RootWeb; var gallery = web.Lists["Web Part Gallery"]; var items = gallery.Items; for (int i = items.Count - 1; i >= 0; i--) { var item = items[i]; if (parts.Contains(item.File.Name)) { item.Delete(); } } }
  • 25. DEMO Cleaning the Web Part Gallery
  • 26. Creating Web Part Page Templates  Create a site page  Set base type to Microsoft.SharePoint.WebPartPages.WebPartPage  Add one or more web part zones to page  Provision page instances using Module <%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %> <!-- Other register directives --> <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, …" %> <%@ Page Language="C#" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage" MasterPageFile="~masterurl/default.master" %> <asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server"> <WebPartPages:WebPartZone ID="MainZone" runat="server" FrameType="TitleBarOnly" Title="Main Web Part Zone" /> </asp:Content>
  • 27. Adding Web Parts to Web Part Pages  Use SPLimitedWebPartManager  Get reference from property of Page object  Use SPLimitedWebPartManager.AddWebPart to add var page = web.GetFile("SiteAssets/Test02.aspx"); using (var manager = page.GetLimitedWebPartManager( PersonalizationScope.Shared)) { if (!manager.WebParts.Contains(webPartTitle)) { var part = new MostPopularProducts2.MostPopularProducts2(); part.Title = "Most Popular Products"; part.Category = "Condiments"; part.Year = 1997; manager.AddWebPart(part, "Left", 0); } } Note: Contains method shown in code sample is a custom extension
  • 28. DEMO Creating Web Part Pages and Adding Web Parts
  • 29. Additional Stuff  Closing versus deleting web parts  Closing a web part does not remove it from page  Having many closed web parts on a page can degrade performance  Set AllowClose to false to remove option to close from web part verbs  Versioning  DO NOT change the assembly version of your assemblies  SharePoint stores the full name with version of all web parts in galleries and on pages  Use the AssemblyFileVersion instead
  • 30. Thank You  Big thanks to the organizers, sponsors and you for making this event possible  Please fill out your evaluation  Please keep in touch rob@robwindsor.com @robwindsor msmvps.com/blogs/windsor

Editor's Notes

  1. 2