This document provides an overview and agenda for an advanced SharePoint 2010 and 2013 web part development session. The agenda includes discussions on visual web parts, persistent web part properties, editor parts, connectable web parts, web part verbs, asynchronous web parts, the web part gallery, and web part pages. It also includes demos of these various web part features. The presenter is introduced as a senior SharePoint architect and Microsoft MVP with experience in web part and SharePoint development.
2. About Me
• Senior SharePoint Architect with Portal Solutions
• 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
• Visual Web Parts
• Persistent Web Part Properties
• Editor Parts
• Connectable Web Parts
• Web Part Verbs
• Asynchronous Web Parts
• Web Part Gallery
• Web Part Pages
5. Visual Web Parts
• Visual web parts traditionally combine a web part with a
user control
• User controls have full design experience in Visual Studio
• User interface and code behind defined in user control
• Web part “injects” user control dynamically using
Page.LoadControl
private const string _ascxPath = @"~/_CONTROLTEMPLATES/.../MyUserControl.ascx";
protected override void CreateChildControls()
{
Control control = Page.LoadControl(_ascxPath);
Controls.Add(control);
}
6. Web Parts in Sandboxed Solutions
• Split page rendering
Page code runs in ASP.NET worker process
Sandboxed web part code runs in sandbox worker process
HTML markup and JavaScript from two worker processes merged
• Sandbox restrictions
Reduced set of server object model API
Restricted access outside SharePoint
No elevation of permissions
Cannot deploy files to SharePoint system folders
Must be ASP.NET web parts
Can only use ASP.NET controls
No web part connections
7. Sandbox Visual Web Part Template
• Native visual web part template not compatible
with sandboxed solutions
Attempts to deploy user control to system folders
• Visual Studio 2010 Power Tools introduced a
sandbox compatible template
No user control
Designer makes web part behave like a user control
Markup in user control converted to code at design time
• Visual Studio 2012 only has this template
9. 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; }
11. Cross Site Script Safeguards
• Added in SharePoint 2010
• Indicates developer has taken steps to ensure code is safe
against scripting attacks
• Two key pieces
SafeAgainstScript attribute of SafeControl entry
RequiresDesignerPermission attribute
• Contributors can only set web part properties if:
SafeAgainstScript is true (not the default)
RequiresDesignerPermission is false (default)
13. 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
15. 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
17. 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
19. Web Part Verbs
• Add additional menu options to
dropdown at top-right of Web Part
• Can be handled client-side, server-
side or both.
20. Web Part Verbs
public override WebPartVerbCollection Verbs
{
get
{
var verbs = new List<WebPartVerb>();
var verb1 = new WebPartVerb(this.ID + "_ClientSideRssOpenerVerb",
string.Format("window.open('{0}','RSSXML')", this.FeedUrl));
verb1.Description = "Open RSS Feed in an external window";
verb1.Text = "Open RSS Feed";
verbs.Add(verb1);
var verb2 = new WebPartVerb(this.ID + "_ServerSideRssOpenerVerb",
new WebPartEventHandler(ServerSideVerbHandler));
verb2.Description = "Load the RSS Source Feed.";
verb2.Text = "View RSS Source Feed";
verbs.Add(verb2);
var allverbs = new WebPartVerbCollection(base.Verbs, verbs);
return allverbs;
}
}
22. Asynchronous 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
23. Asynchronous Web Parts
protected void Page_PreRender(object sender, EventArgs e) {
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) {
_feedCaller = GetFeed;
return _feedCaller.BeginInvoke(cb, state);
}
public void EndFeed(IAsyncResult ar) {
var feed = _feedCaller.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 * _hostPart.PageSize).Take(_hostPart.PageSize);
FeedListView.DataSource = posts.ToList();
FeedListView.DataBind();
}
25. 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
26. 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();
}
}
}
28. 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>
29. 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
31. 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
32. Thank You
• Big thanks to the organizers, sponsors and you for making
this event possible
• Please fill out your evaluation
• Please keep in touch
rwindsor@portalsolutions.net
@robwindsor
msmvps.com/blogs/windsor