I have been getting back into SharePoint 2010/2013 development, and already I had flashbacks to when I had worked with 2003 and 2007 when I received errors about my ‘unsafe webpart’. This actually seemed to be a regular occurrence, particularly when changing namespaces or assembly details. I set out to get to the bottom of this, and remembered some old tricks from before that helped in creating this troubleshooting guide.
I am running through this guide on a SP2013 project. 2010 will be different, but much of the same principals apply.
Examples of Errors You nay be Receiving
- A Web Part or Web Form Control on this Page cannot be displayed or imported. The type YourNameSpace.YourPart, YourPart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=SomeToken could not be found or it is not registered as safe.
- An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.
- Could not load type ‘YourNameSpace.YourPart.SomeUserControl’
Typical causes
- Adjusting your namespaces (refactoring is not enough)
- Adjusting your class names
- Modifying .webpart files manually
- Incorrect Site URL targeted in Visual Studio
- GlobalAssemblyCache (GAC) not receiving your DLL.
Troubleshooting Process
Note: CASE SENSITIVITY is important throughout this article. Ensure you are checking casing on your references in code on everything to make sure it matches.
Visual Studio Project
There are several key files to investigate when having this problem as they contain references to the DLL your project creates. The SharePoint project is not always smart enough to update these when adjusting your namespaces or type names through code.
Before continuing, figure out what your Namespace is, and what your Webpart Type is. For example, take the following code I created:
namespace Myblog.WebParts { public class MyWebPart : WebPart { } }
The namespace for my webpart is MyBlog.WebParts. The type is MyWebPart. This is important for checking against the SharePoint files:
.webpart files
If you have a webpart, you will have a .webpart file. Open it up. You will want to ensure that the type name references your namespace and type used for your particular webpart that it references. Check within the metaData field. Here’s an example of my working .webpart file:
<metaData> <type name="Myblog.WebParts.MyWebPart, $SharePoint.Project.AssemblyFullName$" /> <importErrorMessage>$Resources:core,ImportErrorMessage;</importErrorMessage> </metaData>
These files must reference the namespace included with the type.
.ascx files
If your webpart uses user controls, you may have actually added the webpart to the page just fine, but the ASCX files could easily cause a page error as your webpart tries to render if it tries to reference an invalid assembly. Open up your ASCX file where the extension is purely that. (not aspx.cs)
At the top, confirm that you have this line, and that it matches up to your namespace and type. Chances are the ascx CodeBehind attribute is correct as VS manages this one well.
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyUserControl.ascx.cs" Inherits="MyBlog.WebParts.VisualWebPart1UserControl" %>
Note that this is the namespace WITH the type at the end. The type for this one can be checked against in your ascx.cs file (inheriting from : UserControl).
.spdata files
SharePoint projects by default have a hidden .spdata file which is partly responsible for the safe control entry in the web.config. This is located right under your webpart folder. Look at the top of your solution explorer tabbed window for a ‘Show all files’ icon. Then you should be able to see this file and open it up. If you do not have this file, this may be your issue and is not part of the scope for this document. Once you have your spdata file open, you’ll notice a reference to your namespace.
Here’s a working example:
<SafeControl Name="SafeControlEntry1" Assembly="$SharePoint.Project.AssemblyFullName$" Namespace="Myblog.WebParts" TypeName="*" IsSafe="true" IsSafeAgainstScript="false" />
Again, make sure you only put in your namespace there. The TypeName matches against all your types with the wildcard.
web.config
I’m sure most of you already know about this business, but lets double check and be extra certain about this step.
Did you recently change the web you deploy to? Or were you previously working with a different website, then switched over to another one without deploying again? Sometimes its small things like that that come up. Do a quick sanity check,click your project in solution explorer and ensure your Site URL is the website you are trying to get your webpart on. Good? Alright lets continue.
Lets make sure your web.config is in order. In my project, I check my Site URL and I see ‘http://win-j1151qbc1qm:2744/’. So I will go to the IIS directory to ensure everything is alright. Typically yours will be at C:\inetpub\wwwroot\wss\VirtualDirectories. Then I go into 2744 folder and open up the web.config.
Find the SafeControls element. Usually yours will be at the very bottom. If you cant even find your namespace in here, that’s an issue! In most cases, it will be here, and if you checked on .spdata chances are also that it will be OK. Here’s my safe control:
<SafeControl Assembly="MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3b7ec4bdc16ce8b2" Namespace="Myblog.WebParts" TypeName="*" Safe="True" />
Note that the namespace contains only the namespace, and is correct. Assembly=MyAssembly, also correct. You can confirm your assembly name by right clicking your project (not solution) and clicking properties. On the first tab (application) you will see Assembly Name. This must match with Assembly in SafeControls. Default namespace, even if wrong here, doesn’t necessarily mean your webpart will not work, but should be fixed if its unwanted, as it will add new code with that particular namespace. Existing code doesn’t get adjusted from that.
Package Manifest
Alright. Lets look at the Manifest. Under Package, double click your Package.package (or similar). You should see three tabs: design, advanced, and manifest. Open manifest. Things to examine at this point:
- Is your assembly referenced here, it should be!
- Verify your safe control
Feature Manifest
Almost there. Open your feature, double click your feature name. Click Manifest. Things to check:
- .webpart file(s). Make sure your webpart is there, then examine that webpart in your project and ensure you’re working with the right one.
Working yet? Great!
But if not, lets dig EVEN deeper.
What may be happening, is that your DLL may not even be deploying. Package your solution, or just try deploying again, and then head over to your solution folder. Open up bin\Debug to find your .DLL and .WSP files.
Rename your WSP file to have extension .CAB. You should be able to pry it open to see whats going on in there. I personally use WinRAR for peeking inside as it structures it nicely. Things to check:
- Make sure your .DLL is in there! It should have same name as your assembly name is in project properties.
- Open the manifest.xml. Double check that your Assembly is referenced. You should at the very least have something similar to this:
<Assembly Location="MyAssembly.dll" DeploymentTarget="GlobalAssemblyCache"> <SafeControls> <SafeControl Assembly="MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3b7ec4bdc16ce8b2" Namespace="Myblog.WebParts" TypeName="*" /> </SafeControls>
- Investigate your .webpart files inside too, as we did before!
If anything seems odd, check your project. I.e. if you have a more complex project, are you packaging a different/wrong webpart file than intended? Its important to double check EVERYTHING in the WSP as everything should be within this file, and this is past all your code by this point which narrows down complexity.
I really hope you’re not at this point. But I’m still here to help. Lets continue for a bit longer, but I must warn, my hands tire!
Download this VERY useful utility: IlSpy. Open it up, lets make sure your assembly is where it should be. Under file click ‘Open from GAC‘. Search for your assembly name, you can look under your project properties again if you forget.
It SHOULD be in the list! Note the version, culture, public key token, etc that it is registered with in the GAC. You want to double check those all match the references from prior, extra scrutiny on the public key token.
Also, open it up in IlSpy, you can browse through the namespaces and types that the assembly has, the same one SharePoint is communicating with. It should have all the namespaces and types that you are referencing.
Final Notes
I did my best to cover every base for this issue. If anyone finds a location I may have missed that would contribute towards this problem please post! Did this help? Let me know!
2 Comments
Thank you very much for this post !
It solved my problem ! 😀
Thank you. This systematic approach helped me resolve my problem.
Leave a Reply