Sunday, 19 February 2012

SharePoint 2010 Web Parts vs. Visual Web Parts

I have read a lot of SharePoint documentation and articles recently, and one confusing point that kept getting glossed over was whether there was a difference between what was called a “Visual” Web Part and a Web Part by any other name.
The answer is, there is a difference, but not in the .NET type. There is a difference in how the part is implemented and its project type in Visual Studio. The short answer is that a Web Part is “visual” if its implementation includes an ASP.NET user control, i.e. an .ascx file. Creating a project of type “Visual Web Part” from the Visual Studio project wizard creates a project that looks like this:

Notice the automatically-created .ascx user control. Indeed, the code in the Web Part is the same as we would find on a normal part, but in the implementation the user control is instantiated programmatically like this:
01public class VisualWebPart1 : WebPart
02{
03    private const string _ascxPath =
04        @"~/_CONTROLTEMPLATES/VisualWebPartProject2/VisualWebPart1/VisualWebPart1UserControl.ascx";
05
06    protected override void CreateChildControls()
07    {
08        Control control = Page.LoadControl(_ascxPath);
09        Controls.Add(control);
10    }
11}
Trying to deploy this project as a sandboxed solution will fail, since user controls violate the constraints placed on code that runs in the sandbox. There is nothing intrinsically about the code that would prevent its installation as a sandboxed solution, but it will fail when the solution is activated.

Changing a Visual Web Part to a regular Web Part

We can change the Web Part type by manually editing the .spdata file in the project. Visual Studio won’t allow direct access to this file, so we’ll have to browse to it on the filesystem and edit it in notepad.
01<?xml version="1.0" encoding="utf-8"?>
02<ProjectItem Type="Microsoft.VisualStudio.SharePoint.VisualWebPart" DefaultFile="VisualWebPart1UserControl.ascx" SupportedTrustLevels="FullTrust" SupportedDeploymentScopes="Site" xmlns="http://schemas.microsoft.com/VisualStudio/2010/SharePointTools/SharePointProjectItemModel">
03  <Files>
04    <ProjectItemFile Source="Elements.xml" Target="VisualWebPart1\" Type="ElementManifest" />
05    <ProjectItemFile Source="VisualWebPart1.webpart" Target="VisualWebPart1\" Type="ElementFile" />
06    <ProjectItemFile Source="VisualWebPart1UserControl.ascx" Target="CONTROLTEMPLATES\VisualWebPartProject2\VisualWebPart1\" Type="TemplateFile" />
07  </Files>
08  <SafeControls>
09    <SafeControl Name="SafeControlEntry1" Assembly="$SharePoint.Project.AssemblyFullName$" Namespace="VisualWebPartProject2.VisualWebPart1" TypeName="*" IsSafe="true" IsSafeAgainstScript="false" />
10  </SafeControls>
11</ProjectItem>
We are interested only in this line:
1<ProjectItem Type="Microsoft.VisualStudio.SharePoint.VisualWebPart" DefaultFile="VisualWebPart1UserControl.ascx" SupportedTrustLevels="FullTrust"
We can change the Type from VisualWebPart to WebPart and SupportedTrustLevels from FullTrust to All.
The resulting code looks like this:


1<ProjectItem Type="Microsoft.VisualStudio.SharePoint.WebPart" DefaultFile="VisualWebPart1UserControl.ascx" SupportedTrustLevels="All"
Once the change is made, reload the project in Visual Studio, and its type should be recognized as a normal web part. Be sure to remove the user control before attempting to deploy as a sandboxed solution!

No comments:

Post a Comment