SharePoint: Adding Custom Web Part to Page Layout causes No Parameterless Constructor Exception


After adding a custom web part to a publishing page layout using SharePoint Designer, I tried creating a page instance using the page layout and was presented with the following exception;

Exception type: MissingMethodException 
Exception message: No parameterless constructor defined for this object.
at System.RuntimeTypeHandle.CreateInstance(...)
   at System.RuntimeType.CreateInstanceSlow(...)
   at System.RuntimeType.CreateInstanceImpl(...)
   at System.Activator.CreateInstance(...)
   at Microsoft.SharePoint.WebPartPages.SPWebPartReflectionHelper.GetDefaultControl(...)
   at Microsoft.SharePoint.WebPartPages.BinaryWebPartSerializer.GetDefaultControl()
   at Microsoft.SharePoint.WebPartPages.BinaryWebPartSerializer.Serialize(...)
   at Microsoft.SharePoint.WebPartPages.BinaryWebPartSerializer.get_Links()
   at Microsoft.SharePoint.WebPartPages.SPWebPartManager.AddWebPartToStore(...)
   at Microsoft.SharePoint.WebPartPages.SPWebPartManager.AddWebPartInternal(...)
   at Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager.AddWebPartInternal(...)
   at Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager.AddWebPart(...)
   at Microsoft.SharePoint.Publishing.PublishingPage.CopyAllWebParts(...)
   at Microsoft.SharePoint.Publishing.PublishingWeb.<>c__DisplayClass1c.<AddPublishingPage>b__17()
   at Microsoft.Office.Server.Diagnostics.FirstChanceHandler.ExceptionFilter(...)
   at Microsoft.Office.Server.Diagnostics.ULS.SendWatsonOnExceptionTag(...)
   at Microsoft.SharePoint.Publishing.PublishingWeb.AddPublishingPage(...)
   at Microsoft.SharePoint.Publishing.Internal.CodeBehind.CreatePagePage.NewPageItemSave(...)
   at Microsoft.SharePoint.Publishing.Internal.CodeBehind.CreatePagePage.CreateStandardPage(...)
   at Microsoft.SharePoint.Publishing.Internal.CodeBehind.CreatePagePage.ButtonCreatePage_Click(...)
   at System.Web.UI.WebControls.Button.OnClick(...)
   at System.Web.UI.WebControls.Button.RaisePostBackEvent(...)
   at System.Web.UI.Page.RaisePostBackEvent(...)
   at System.Web.UI.Page.ProcessRequestMain(...)

Ok so this particular custom web part works fine when you drop it onto a page using the SharePoint UI, so it seems that SPD has a problem with it, Google turns up some interesting results which may be relevant to you but didn’t help me.

When adding web parts to page layouts, there are typically 2 ways to do it;

  1. Adding them directly to the page layout (.aspx) markup
  2. Adding them using the feature provisioning framework, as I discussed in this post.

In this case I was trying to add my web part directly to the page layout markup (.aspx file), as shown below;

<WebPartPages:WebPartZone id="TopZone" runat="server" title="Top Zone"><ZoneTemplate>
<Artefacts:ContentFusionWebPart runat="server" AggregationSource="GenericList" AggregationScope="SiteCollection" RowLimitSafe="5" RowLimit="10" __MarkupType="vsattributemarkup" __WebPartId="{8A40A9D7-0575-4031-94EF-EDDDAABE64BF}" WebPart="true" __designer:IsClosed="false" partorder="2"></Artefacts:ContentFusionWebPart>

</ZoneTemplate></WebPartPages:WebPartZone>

In the case of this web part, there were 2 properties which were custom enumerations, AggregationSource and AggregationScope.

Removing these properties from the markup fixed the problem and the web part worked correctly in both SPD and in SharePoint when creating a new page.

Another problem I had was with the use of non CLS-compliant properties, SharePoint Designer will complain about these types of property when you add a web part to a page;

non CLS-Compliant properties
non CLS-Compliant properties

In this case the property is a UInt type, if you ignore this error, in my environment SharePoint would throw the same “No Parameterless Constructor” exception.

One possible workaround to this problem if you must reference such properties in SharePoint Designer is to modify your code, so that you have both a CLS and non CLS compliant property representing the same value, internally in your code you determine which property value is the one to use, as shown below;

public class MyWebPart : WebPart
{
	public MyWebPart()
	{
		RowLimitSafe = int.MaxValue;
	}
	[Personalizable(PersonalizationScope.Shared)]
	[WebBrowsable(true)]
	[WebDisplayName("Row Limit")]
	public uint RowLimit { get; set; }
	public int RowLimitSafe { get; set; }
	private uint GetRowLimit()
	{
		uint ret;
		if (RowLimitSafe != int.MaxValue)
			ret = (uint)Math.Max(RowLimitSafe, 0);
		else
			ret = Math.Max(RowLimit, 0);
		return ret;
	}
}

One property (the non CLS-compliant one) is exposed as WebBrowsable (so it’s visible in the SharePoint UI) while the other (CLS compliant) property is the one you’d reference from SharePoint Designer, since they are both public this works out ok.

The property not exposed as WebBrowsable is not serialised to the content database or to a .webpart file if you export the web part from the SharePoint UI.

Published by

Phil Harding

SharePoint Consultant, Developer, Father, Husband and Climber.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s