Web Parts are the foundation of user interfaces in SharePoint. As a developer, it's relatively easy (particularly with the Visual Web Part) to build something simple and get it deployed. But what do you do when you need to add editable properties or when you need to connect two Web Parts together? This fast-paced, demo-heavy session covers the more advanced aspects of building Web Parts for SharePoint on-premises and SharePoint Online. We’ll take a look at creating custom editor parts, constructing connected Web Parts, and how to render Web Parts asynchronously. We’ll also explore how to build JavaScript-only Web Parts that will work with SharePoint Online.
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)
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/
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();
}
}
}
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
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