Monday, June 9, 2014

Change the namespace on a web part solution

I rarely like the way Visual Studio handles namespaces within a solution. I like to organize my code with folders and such and Visual Studio likes to add the folder hierarchy to the namespace. However, when I change the namespace name on a web part solution I invariably get the "Web Part Error: A Web Part or Web Form Control on this Page cannot be displayed or imported. The type {your web part class type} could not be found or it is not registered as safe." error, then I spend 30-60 minutes scouring the web to remember how to fix this. So, to save me that frustration in the future I am documenting what I have found to be the solution.

Lets take for example, my desired namespace is "C2.AcmeCorp.Relationships" and my Web Part is named "DisplayRelationships":

0) Retract your current deployed solution, just to insure cleanup of the web.config.

1) You must manually update a hidden file under the web part named "SharePointProjectItem.spdata". Visual Studio can display and edit this file, you must click the "Show All Files" icon in solution explorer in order to see it. You must manually update the SafeControl Namespace property to your new namespace name, Visual Studio does not do this for you. For example:

<SafeControls>
  <SafeControl Name="SafeControlEntry1"
               Assembly="$SharePoint.Project.AssemblyFullName$" 
               Namespace="C2.AcmeCorp.Relationships
               TypeName="*" 
               IsSafe="true" 
               IsSafeAgainstScript="false" />
</SafeControls>

2) You must insure the .webpart file type name is correct. In my example, the DisplayRelationships.webpart file should be updated to look like the following:

<metaData>
 <type Name="C2.AcmeCorp.Relationships.DisplayRelationships$SharePoint.Project.AssemblyFullName$" />
  </importErrorMessage>$Resources:core,ImportErrorMessage</importErrorMessage>
</metaData>

3) Redeploy your solution. In my example the updated web.config SafeControl entry should look like the following after I have redeployed my solution:

<SafeControls>
  <SafeControl Assembly="C2.AcmeCorp.Relationships, Version=1.0.0.0 Culture=neutral, PublicKeyToken=16de7ad7af136a9"
               Namespace="C2.AcmeCorp.Relationships
               TypeName="*" 
               Safe="True" />
</SafeControls>