Blog of Sundar Narasiman

Profiling SharePoint code using DebugView tool

I thought of  writing a post on profiling the SharePoint code using DebugView tool. Because DebugView is bit undermined and it’s not widely used for profiling SharePoint code. You can think of leveraging DebugView tool, when you can’t do a remote debugging and when the Developer Dashboard does not give you much information. DebugView comes handy in such scenarios and it is also less invasive approach of profiling the code.

The whole idea is to place set of Debug statements in your code and run the DebugView tool on the server. Then DebugView tool captures all the output from Debug statements and lists them.

I’ve an event handler by name ‘TestListEventHandler’ attached to a custom list called ‘TestCustomList’

pic1

Now I’ll be adding the Debug statements (System.Diagnostics.Debug.WriteLine) to the event handler methods.

My event handler implementation looks like the following with Debug statements.

public override void ItemAdding(SPItemEventProperties properties)
       {
           System.Diagnostics.Debug.WriteLine("Entering Item Adding Event");
           base.ItemAdding(properties);
           System.Diagnostics.Debug.WriteLine("Exiting Item Adding Event");
           

       }

       /// <summary>
       /// An item is being updated.
       /// </summary>
       public override void ItemUpdating(SPItemEventProperties properties)
       {
           System.Diagnostics.Debug.WriteLine("Entering Item updating Event");
           base.ItemUpdating(properties);
           System.Diagnostics.Debug.WriteLine("Exiting Item updating Event");
       }

       /// <summary>
       /// An item is being deleted.
       /// </summary>
       public override void ItemDeleting(SPItemEventProperties properties)
       {
           System.Diagnostics.Debug.WriteLine("Entering Item deleting Event");
           base.ItemDeleting(properties);
           System.Diagnostics.Debug.WriteLine("Exiting item deleting Event");
       }

       /// <summary>
       /// An item is being checked in.
       /// </summary>
       public override void ItemCheckingIn(SPItemEventProperties properties)
       {
           System.Diagnostics.Debug.WriteLine("Entering Item checingin Event");
           base.ItemCheckingIn(properties);
           System.Diagnostics.Debug.WriteLine("Exiting Item checking-in Event");
       }

       /// <summary>
       /// An item is being checked out.
       /// </summary>
       public override void ItemCheckingOut(SPItemEventProperties properties)
       {
           System.Diagnostics.Debug.WriteLine("Entering Item checking out Event");
           base.ItemCheckingOut(properties);
           System.Diagnostics.Debug.WriteLine("Exiting Item checking out");
       }

       /// <summary>
       /// An item is being unchecked out.
       /// </summary>
       public override void ItemUncheckingOut(SPItemEventProperties properties)
       {
           System.Diagnostics.Debug.WriteLine("Entering Item unchecking out Event");
           base.ItemUncheckingOut(properties);
           System.Diagnostics.Debug.WriteLine("Exiting Item checking out");
       }

       /// <summary>
       /// An attachment is being added to the item.
       /// </summary>
       public override void ItemAttachmentAdding(SPItemEventProperties properties)
       {
           System.Diagnostics.Debug.WriteLine("Entering Item attachment Adding Event");
           base.ItemAttachmentAdding(properties);
           System.Diagnostics.Debug.WriteLine("Exiting Item attachment Adding Event");
       }

       /// <summary>
       /// An attachment is being removed from the item.
       /// </summary>
       public override void ItemAttachmentDeleting(SPItemEventProperties properties)
       {
           System.Diagnostics.Debug.WriteLine("Entering Item attachment deleting");
           base.ItemAttachmentDeleting(properties);
           System.Diagnostics.Debug.WriteLine("Exiting Item attachment deleting Event");
       }

       /// <summary>
       /// A file is being moved.
       /// </summary>
       public override void ItemFileMoving(SPItemEventProperties properties)
       {
           System.Diagnostics.Debug.WriteLine("Entering Item file moving Event");
           base.ItemFileMoving(properties);
           System.Diagnostics.Debug.WriteLine("Exiting Item file moving Event");
       }

       /// <summary>
       /// An item was added.
       /// </summary>
       public override void ItemAdded(SPItemEventProperties properties)
       {
           System.Diagnostics.Debug.WriteLine("Entering Item Added Event");
           base.ItemAdded(properties);
           System.Diagnostics.Debug.WriteLine("Exiting Item Added Event");
       }

Now I’ll be running the DebugView tooll with the following capture settings

pic2

DebI’ll start adding an item item to the custom list.

pic3

DebugView captures the debug statement emitted from the code like the following.

pic4

We can measure execution test time of a particular method/statement by placing them within a enclosed Debug statements (like mentioned in the above code snippet). The tool would give you exact time (in milliseconds) when the particular debug statement is executed. If we can compute the difference in time reported between two debug statements, that would give us an exact time it takes to complete a task (a statement or a method or an external call).

The other advantage of debug view is that we can figure out the execution path of our code at runtime, like how many times a method is called or has a method been skipped etc. The log produced by DebugView can also be exported into a separate file. 

 Subscribe to my blog

SharePoint 2010 Recommended practices for disposing objects–part3

This post is the continuation of my previous post SharePoint 2010 Recommended practices for disposing objects – part2.

1. Automatic Disposal of SPWeb objects created when accessing SPWeb.ParentWeb property

It is not recommended to explicitly dispose SPWeb objects created by accessing SPWeb.ParentWeb property. The SharePoint 2010 Framework (both the SharePoint Foundation 2010 and SharePoint Server 2010) takes care of automatically disposing this object.

using (SPSite oSPSite = new SPSite("http://yoursitecollection")) 

{

using (SPWeb oSPWeb = oSPSite.OpenWeb())

{

SPList oSPList =oSPWeb.Lists ["Shared Documents"];

SPWeb oSPWebNew = oSPList.ParentWeb; //Do not explicitly dispose this

}

}
2. Explicit Disposal of SPWeb objects created when accessing SPWeb.ParentWeb property

It is recommended to explicitly dispose SPWeb objects created by accessing SPWeb.Webs property. In the following code-snippet explicitly dispose oSPWebNew object by an explicity try-finally clause. Because this is not handled by the framework

Using (SPSite oSPSite = new SPSite ("http://yoursitecollection"))

{

Using (SPWeb oSPWeb = oSPSite.OpenWeb ())

{

foreach (SPWeb oSPWebNew in oSPSite.Webs)

{

try //use a try-finally block to explicitly dispose every instance of oSPWebNew

{

// ...

}

finally

{

if(oSPWebNew != null)

oSPWebNew.Dispose ();

}

}

} // Dispose is automatically called for oSPWeb

}
3. Explicit Disposal of SPWeb objects created by when invoking SPWeb.Webs.Add method

It is recommended to explicitly dispose SPWeb objects created by invoking SPWeb.Webs.Add method. In the following code snippet, the SPWeb object created by invoking SPWeb.Webs.Add method need to be explicitly disposed using ‘Using’ clause.

using (SPSite oSPSite = new SPSite("http://yoursitecollection"))

{

using (SPWeb oSPWeb = oSPSite.OpenWeb())

{

//Explicitly use the Using Clause to dispose SPWeb objects

using (SPWeb oSPWebNew = oSPWeb.Webs.Add(strWebUrl))

{

}

} 

}
4. Explicit Disposal of SPWeb objects when invoking SPWeb.Webs[] index operator

It is recommended to explicitly dispose SPWeb objects created by accessing SP.Webs[] index operator in web collection. In the following snippet, the object oSPWeb2 needs to be explicitly disposed.

int i;

SPWeb oSPWeb, oSPWebNew;

SPSite oSPSite = new SPSite ("//yoursitecollection");

using (oSPWeb = oSPSite.OpenWeb())

{

for(i = 0;i < oSPWeb.Webs.Count;i++)

{

oSPWebNew = oSPWeb.Webs[i];

//do some arbitrary operation

oSPWeb2.Dispose();

}

}
5. Explicit Disposal of SPWeb objects when invoking Microsoft.SharePoint.Portal.SiteData.Area.Web Property

It is recommended to explicitly dispose SPWeb objects created by accessing SharePoint.Portal.SiteData.Area. Though Area and AreaManager is obsolete in SharePoint 2010 and it exists more in legacy code. This should be considered while migrating legacy SharePoint code to SharePoint 2010

int i;

SPWeb oSPWeb, oSPWebNew;

SPSite oSPSite = new SPSite("//yoursitecollection");

using(oSPWeb = oSPSite.OpenWeb())

{

for(i = 0;i < oSPWeb.Webs.Count;i++)

{

oSPWebNew = oSPWeb.Webs[i];

//do some arbitrary operation

oSPWeb2.Dispose();

}

}
6. Explicit Disposal of SPWeb objects when accessing Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager property

It is recommended to explicitly dispose SPLimitedWebPartManager object while accessing Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager property. Because SPLimitedWebPartManager internally creates an instance of SPWeb object .

using (SPSite oSPSite = new SPSite("http://youroSPSite"))

{

using (SPWeb oSPWeb = oSPSite.OpenWeb())

{

SPFile oPage = web.GetFile("Folder_Name/Source_Page");

SPLimitedWebPartManager oSPLimitedWebPartManager =

oPage.GetLimitedWebPartManager(PersonalizationScope.Shared);

//Explicity dispose oSPLimitedWebPartManager object

oSPLimitedWebPartManager.Web.Dispose();

} 

}
7. Handling Microsoft.SharePoint.Publishing.PublishingWeb objects

The PublishingWeb and PublishingWebCollection come into picture when we develop using SharePoint Server 2010. It is recommended to explicitly close the each instance of PublishingWeb object accessed inside PublishingWebCollection.

Using (SPSite oSPSite = new SPSite("http://youroSPSite"))

{

Using (SPWeb oSPWeb = oSPSite.OpenWeb())

{

PublishingWeb oPublishingWeb = PublishingWeb.GetPublishingWeb(oSPWeb);

PublishingWebCollection oPublishingWebCollection = oPublishingWeb.GetPublishingWebs();

foreach (PublishingWeb oPublishingWebNew in oPublishingWebCollection)

{

try

{

// ...

}

finally

{

if(oPublishingWebNew != null)

oPublishingWebNew.Close();

}

}

}

}
This post completes the 3 part series of guidance on disposing SharePoint objects.

 Subscribe to my blog

SharePoint 2010 Recommended practices for disposing objects–Part2

This post is the continuation of the post titled SharePoint 2010 Recommended Practices for disposing objects – part1

1. Disposing Framework Created Objects

a)The SPSite objects created through ‘Add’ method of SPSiteCollection class should be disposed explicitly. This is not managed by the Framework. Only objects created from SPContext is managed by the Framework.

SPWebApplication oSPWebApplication = new SPSite("http://yoursitecollection").WebApplication;

SPSiteCollection oSPSiteCollection = webApp.Sites;

using (SPSite oSPSiteCollection = siteCollections.Add("sites/myNewSiteCollection", "DOMAIN\User", 

"test.user@testdommain.com"))

{

}

b)Explicitly Dispose SPSite objects created through SPSiteCollection[Index] property. Because accessing SPSiteCollection[Index] property

returns a new instance of SPSite object. This needs to be explicitly disposed. In the following case, the oSPSiteNew object needs to be explicitly disposed either using try-finally or using clause.

using (SPSite oSPSSiteOuter = new SPSite("http://yoursitecollection"))

{

SPSite oSPSiteNew = null;

try

{

SPWebApplication oSPWebApplication = oSPSiteInner.WebApplication;

SPSiteCollection oTempSiteCollections = webApp.Sites;

oSPSiteNew = siteCollections[0];

}

finally

{

if (oSPSiteNew != null)

oSPSiteNew .Dispose();

}

}

c)Explicitly dispose SPSite objects accessed inside for-each loop using try-finally clause.

foreach (SPSite oSPSiteTemp in siteCollections)

{

try

{

// ...

}

finally

{

if(oSPSiteTemp != null)

oSPSiteTemp.Dispose();

}

}

d)Explicitly dispose SPWeb objects created through Add method (SPSite.AllWebs.Add Method) of SPWebCollection class.

using (SPSite oSPSite = new SPSite("http://yoursitecollection"))

{

using (SPWeb oSPWeb = oSPSite.AllWebs.Add("site-relative URL"))

{

} // oSPWeb is automatically disposed by Using clause

} // oSPSite is automatically disposed by Using clause

e)Explicitly Dispose SPWeb objects accessed through SPWebCollection[Index] property. Because accessing SPWebCollection[Index] property returns a new instance of SPWeb object. This needs to be explicitly disposed. In the following the object oSPWebNew needs to be explicitly disposed by using clause or try-finally clause.

using (SPSite oSPSite = new SPSite("http://yoursitecollection"))

{

using (SPWeb oSPWeb = siteCollection.OpenWeb())

{

SPWebCollection webCollection = oSPSite.AllWebs; 

using (SPWeb oSPWebNew = webCollection.Add(strWebUrl))

{

//this will dispose oSPWebNew

}

} // 

}

f)Explicitly dispose SPWeb objects accessed inside for-each loop using ‘try-finally’ clause

foreach (SPWeb oSPWebNew in oSPSite.AllWebs)

{

try

{

// ...

}

finally

{

if(oSPWebNew != null)

oSPWebNew.Dispose();

}

}

2.Disposing SPWeb objects created through SPSite.OpenWeb()

Explicitly dispose SPWeb objects created through OpenWeb method. Because OpenWeb method creates a new instance of SPWeb object, which is not managed by the framework

using (SPSite oSPSite = new SPSite("http://yourserver"))

{

using (SPWeb web = oSPSite.OpenWeb())

{

} // SPWeb object web.Dispose() automatically called.

}

3.Disposing SPSite objects accessed through SPSite.RootWeb property

a)Do not explicitly dispose SPSite.RootWeb property. This does not hold good for SharePoint Server 2010 and SharePoint Foundation 2010 anymore. The RootWeb property is internally disposed by SP Foundation 2010 or SP Server 2010

b)Do not explicitly call Dispose method on SPSite.RootWeb property

4.Disposing SPSite objects created through Microsoft.Office.Server.UserProfiles.PersonalSite

Explicitly dispose SPSite objects created by accessing that Microsoft.Office.Server.UserProfiles.PersonalSite property

using (SPSite siteCollection = new SPSite("http://yoursitecollection"))

{

UserProfileManager oUserProfileManager = new UserProfileManager(ServerContext.GetContext(siteCollection));

UserProfile oUserProfile = oUserProfileManager.GetUserProfile("domain\username");

using (SPSite oSPSiteNew = oUserProfile.PersonalSite)

{

//enclosed using clause will take care of disposing SPSite objected created by accessing the PersonalSite property

}

}

 Subscribe to my blog

SharePoint 2010 Recommended Practices for disposing objects–Part1

I thought of collating set of best practices around disposing the SharePoint objects. This three part series of articles primarily focuses around that.

1. Disposal of SharePoint Objects

All the SharePoint Foundation 2010 and SharePoint Server 2010 object models implement IDisposable interface. It is recommended to explicitly dispose SharePoint 2010 objects that implement this interface. Because the large part of SharePoint Foundation 2010 object model has unmanaged objects, only a small set of it is managed objects. Do not rely on Garbage collector to release unused SP Foundation objects. It is recommended to explicitly dispose them.

Using Statement for disposing objects

a)The Using Statement can be leveraged to automate the disposal of SharePoint objects that implements IDisposable interface

string test;

using(SPSite oSPsite = new SPSite("http://yoursitecollection"))

{

using(SPWeb oSPWeb = oSPSite.OpenWeb())

{

test = oSPWeb.Title;

test = oSPWeb.Url;

}

}

b)The common language runtime translate ‘Using’ statement into a finally block and disposes the object. Using statements should be used

with Caution for the objects instantiated through SPContext.

c)Do not leverage ‘Using’ statements for SPSite or SPWeb objects that get instantiated through SPContext like the following.

using( SPWeb web = SPControl.GetContextWeb(HttpContext.Current)) { … }

d)In this case the ‘SPContext’ object is managed by SharePoint 2010 framework. This should not be used in ‘Using’ clause.

e)Leverage ‘Using’ statements for every new instance of SPSite or SPWeb created explicitly by the user (not created through SPContext). The following statement is problematic. Because the ‘Using’ statement takes care of only SPWeb, not the SPSite object. In this case, the SPSite object is created, but never disposed.

using (SPWeb web = new SPSite(SPContext.Current.Web.Url).OpenWeb())

{

} // SPWeb object web.Dispose() automatically called.

f)This problem can be fixed by nesting a ‘Using’ statement for SPSite within another ‘Using’ statement for SPWeb.

void NestingUsingStatements()

{

using (SPSite oSiteCollection = new SPSite(SPContext.Current.Web.Url))

{

using (SPWeb oSPWeb = siteCollection.OpenWeb())

{

// 

} // SPWeb object web.Dispose() automatically called.

} // SPSite object siteCollection.Dispose() automatically called.

}

2. Try-Catch-Finally statement for disposing objects

The alternative approach is to leverage Try-Catch-Finally block for disposing unused objects.

a)Leverage catch block to handle exceptions and finally block to dispose unused objects. Do not leave ‘Catch’ block empty.

try

{

oSPSite = new SPSite("http://yourserver");

oSPWeb = oSPSite.OpenWeb(..);

str = oSPWeb.Title;

}

catch(Exception e)

{

// Handle exception, log exception, etc.

}

finally

{

if (oSPWeb != null)

oSPWeb.Dispose();

if (oSPSite != null)

oSPSite.Dispose();

}

b) Always check for ‘Null’ in the finally block before disposing objects.

c)Try-Catch-Finally block can be leveraged to dispose objects created inside for-each loop.

d)Whenever the SharePoint code performs a Re-direct using Response. Redirect, it is recommended to dispose the objects explicitly before redirect. Usually finally block never gets executed during the re-direct.

try

{

oSPSite = new SPSite("http://server");

oSPWeb = oSPSite.OpenWeb(..);

str = oSPWeb.Title;

if (oSPWeb != null)

oSPWeb.Dispose();

if (oSPSite != null)

oSPSite.Dispose();

Response.Redirect("newpage.aspx");

}

catch(Exception e)

{

}

finally

{

if (oSPWeb != null)

oSPWeb.Dispose();

if (oSPSite != null)

oSPSite.Dispose();

}

e)If an object is created using ‘new’ operator , it is recommended to dispose the object

void ExplicitDisposeMethod()

{

SPSite oSPSiteCollection = null;

try

{

oSPSiteCollection = new SPSite("http://moss");

}

finally

{

if (oSPSiteCollection != null)

oSPSiteCollection.Dispose();

}

}

f)Do not share SPRequest objects across threads

g)Do not store SharePoint objects (SPSite and SPWeb) in static variables

Please refer part2 of this article for continuation …

 Subscribe to my blog

Programmatically update Infopath Form XML using c# code

This article would share a code-snippet that updates the Infopath form XML.  In my portal, I’m performing data-acquision using Infopath forms for a Infopath-content type workflow scenario. This scenario is all about an employee appraisal workflow. I’ve a business requirement to mark the ‘IsManager’ column as ‘Yes’ , when the employee gets promoted as Manager. This forced me to think a way to programmatically update the Infopath form XML using c# code. The following is the c# code that can be used to programmatically update the Infopath Form XML.

                        SPWeb   oWeb = SPContext.Current.Web;                       
                        SPList _list = oWeb.Lists[“TestFormLib”];
                        MemoryStream oMemoryStream = new MemoryStream(item.File.OpenBinary());
                        XmlTextReader oReader = new XmlTextReader(oMemoryStream);

                        XmlDocument oDoc = new XmlDocument();
                        oDoc.Load(oReader);

                        oReader.Close();
                        oMemoryStream.Close();

                        XmlNamespaceManager nameSpaceManager = new XmlNamespaceManager(oDoc.NameTable);
                        nameSpaceManager.AddNamespace(“my”, “http://schemas.microsoft.com/office/infopath/2003/myXSD/2009-06-11T12:44:57“);

                        doc.DocumentElement.SelectSingleNode(“my:IsManager”, nameSpaceManager).InnerText = “Yes”;
                        System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
                        SPFile oSPFile = oWeb.Folders[“TestFormLib”].Files.Add(item.File.Name.ToString(), (encoding.GetBytes(doc.OuterXml)), true);
                        item.File.Update();

 

 Subscribe to my blog

Office 365 ondemand web casts

I tried to collate the list of office 365 webcasts that are published this month (July 2011). They are listed below:-

Office 365 Jump Start: Microsoft Office 365 Overview for IT Pros

http://technet.microsoft.com/en-us/edge/video/office-365-jump-start-01-microsoft-office-365-overview-for-it-pros

 

Office 365 Jump Start: SharePoint Online Overview

http://technet.microsoft.com/en-us/edge/office-365-jump-start-12-sharepoint-online-overview

 

Office 365 Jump Start: SharePoint Online Administration

http://technet.microsoft.com/en-us/edge/office-365-jump-start-13-sharepoint-online-administration

 

Office 365 Jump Start: SharePoint Online Extensibility & Customization

http://technet.microsoft.com/en-us/edge/ce-365-jump-start-14-sharepoint-online-extensibility-customization

 

How Microsoft IT does Business Intelligence

http://blogs.technet.com/b/tothesharepoint/archive/2011/06/06/how-does-microsoft-do-bi.aspx

Steps to Configure SharePoint 2010 Information Worker Demonstration and Evaluation Virtual Machine

This article would cover the necessary steps to configure the SP 2010 Information Worker Demo VPC. The easiest way to have a development environment for personal learning need is to download the SharePoint 2010 Information Worker Demonstration VPC and configure it for your needs, rather then setting up a dev server-farm from scratch.

 

Though most of the steps to configure this VPC is available in Microsoft’s guidance, I’d try to cover the things which are not there in MSDN guidance and would make it more comprehensive.

1. Download the VM files from Microsoft site and run the application file 2010-7a.part01.rar

2. This would extract all the 20 files into a large VM dump (2010-7a.vhd)

3. On the extracted folder, you’ll find a configuration file

image

<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
<configuration>
  <SnapShotDataRoot type="string"></SnapShotDataRoot>
  <ExternalDataRoot type="string"></ExternalDataRoot>
  <vhd>
    <source type="string">E:VMsa-andcar2010-7aVirtual Hard Disks2010-7a.vhd</source>
    <target type="string"></target>
  </vhd>
  <VmStateCopied type="bool">true</VmStateCopied>
</configuration>

4. By default the “<Source type-“string”> will have the path of E:VMsa-andcar2010-7aVirtual Hard Disks2010-7a.vhd. You need to change it to the path of your local PC, where the .vhd file is saved. Otherwise, you’ll get an error when you to run this VM in the hyper-v. In my case, I’ve changed the path to D:SP 2010 VM7a2010-7aVirtual Hard Disks2010-7a.vhd.

5. The next step is to define the Network connections in the Hyper-V.

Start Hyper-V Manager from Control Panel -> Administrative Tools

Click Virtual Network Manager

Choose New virtual network in the Virtual Networks pane

Choose Internal from the type list and click Add

 Enter a name of Internal and click OK

image

6. Start menu -> right-click Network –> Properties

    Click Change adapter settings

    Locate the adapter corresponding to ‘Internal’,

    image

    Right click and choose properties

    Double click on IPV4 and set the following IP addresses.

    image

7. The next steps is to define the Internet Connection (External) for the VPC.

On the Virtual Network Manager define an ‘External’ network connection.

image

Now you’ll see a new network connection called ‘External’ in the Network connections

image

I’ve set up wireless network connection already on my windows server 2008 hosting SP 2010 VPC. The name of the connection

is Wireless Network Connection.

image

Right click on wireless network connection –> properties –> Sharing

Check ‘ Allow other network users to connect through this computer’s internet connection’.

Under home networking connection chose the network connection name corresponding to External Adapter defined in hyper-v. In my case it is VLAN2.

image

This will allow the VM to access the internet.

8. Import the Virtual Machine into hyper-v. Otherwise, you can create a brand-new Virtual Machine with the required custom settings using the extracted .vhd file.

9.Start the virtual image

10. Once the machine starts log in as administrator and password is pass@word1

11. The next step is to do re-arming. The re-arming needs to be done after 10 days from the initial usage.

 Run “slmgr –rearm” (no quotes) in the command prompt to complete re-arming.

12. Last, but not least, add the following host entries

127.0.01                    intranet.contoso.com

127.0.01                    finweb.contoso.com

127.0.01                    lcaweb.contoso.com

127.0.01                    itweb.contoso.com

This completes the configuration for SP 2010 Information Worker demonstration VPC.

 

 Subscribe to my blog

Create SharePoint 2010 Visual Web Parts as Sandboxed Solution with Visual Studio 2010 Power Tools

This article will focus on how to create SharePoint 2010 Visual Web Parts as Sandboxed Solution. In the initial release of SP 2010, the Sandboxed Solution Architecture had restriction in terms of supporting Visual Web Parts in the Sandboxed environment. This has been fixed by the recent release of Visual Studio Power Tools for SharePoint 2010, which helps to create Visual Web Parts for Sandboxed environment.

Here are the steps below :-

File –> New –> Project –> Empty SharePoint Project

image

 

Then choose ‘ Deploy as Sandboxed Solution’.

image

Click ‘Finish’.

Add –> New Item –> Visual Web Part (Sandboxed)

image

Implement some arbitrary functionality inside the web part.

image

Right click on Solution Explorer –> Deploy

Now you can see the Sandboxed Solution available in the Solutions Gallery.

image

Caveat

Event though the Visual Studio Power Tools supports Sandboxed Solution, there are some caveats/limitations around that.  The following are not supported.

1. SharePoint Web Controls and some advanced ASP.NET controls

2. Use of “<@ Assembly Src=” directive is not supported

3. Java Script debugging is not supported in Visual Studio.

 Subscribe to my blog

Restrictions in SharePoint 2010 Sandboxed Solutions – Part 2

The code inside SharePoint 2010 Sandboxed Solutions is limited by code access security policy restrictions. The code access security policy for the sandboxed solution worker process is defined in the %ProgramFiles%Common FilesMicrosoft Sharedweb server extensions14CONFIGwss_usercode.config file and it is referenced in %ProgramFiles%Common FilesMicrosoft Sharedweb server extensions14UserCode.

The following permission levels are denied by code access security policy.

No

Denied Permissions

Impact

1

DirectoryServicesPermission

2

DnsPermission

3

EnvironmentPermission

4

EventLogPermission

5

FileIoPermission

Cannot read/write to file system

6

IsolatedStorageFilePermission

7

PrintingPermission

8

ReflectionPermission

9

RegistryPermission

10

SecurityPermission

Cannot access unmanged code, Threads, App Domains etc.

11

SMTPPermission

Cannot access .NET Reflection APIS and non-public class & members in managed code

12

SqlClientPermission

13

SocketPermission

14

UIPermission

15

WebPermission

 

The following permission levels are granted by code access security policy.

No

Granted Permissions

Impact

1

SharePointPermission.ObjectModel

2

ASPnetHostingPermission=Minimal

Can execute resources, but not read/write access to resources

3

SecurityPermission.Execution

 

This completes the final part (Part 2) of the article ‘Restrictions in SharePoint 2010 Sandboxed Solutions’.

 Subscribe to my blog

Full Trust Proxies in SharePoint 2010 Sandboxed Solution – Faqs

  1. What is full trust proxy in the context of SharePoint 2010 Sandboxed Solution?

    A full trust proxy is a mechanism that allows Sandboxed Solution to make a call to trusted assembly outside the Sandbox environment. The trusted assembly can be designed to make external calls (to database or web services), which Sandbox solutions cannot reach. This needed, because not all the SharePoint 2010 solutions might want to live as Sandboxed (with restrictions). In most of the cases, the assemblies inside SharePoint solutions might want to make external calls (to a database or to a web service).

     

  2. How to create a full trust proxy operation in Sandboxed Solution?

    Here are the steps required to create full trust proxy operation using Visual Studio:-    

    1. Create a farm solution , create a c# class that is derived from SPProxyOperation and override Execute method
    2. Create another c# class (in the same solution), that is derived from SPProxyOperationArgs. Pass an instance of this class to the Execute method of SPProxyOperation class.
    3. Create a Feature Receiver to register operation with SharePoint Foundation User Code Service
    4. In the Sandboxed Solution project, create a class that calls the proxy operation
    5. Deploy the Sandboxed solution

       

  3. In which process does the full trust proxy runs?

    The full trust proxy does not run in w3wp.exe, rather it runs in SPUCWorkerProcessProxy.exe.

     

  4. How to programmatically activate the full trust proxy with user code service?

    The following is the code snippet for activating full trust proxy.

     

         SPProxyOperationType proxyOperationType = new SPProxyOperationType(type.Assembly.FullName, type.FullName);

    SPUserCodeService userCodeService = SPUserCodeService.Local;

    userCodeService.ProxyOperationTypes.Add(proxyOperationType);

    userCodeService.Update();

     

  5. How to programmatically de-activate the full trust proxy with user code service?

    The following is the code snippet for de-activating full trust proxy.

 

     SPProxyOperationType proxyOperationType = new SPProxyOperationType(type.Assembly.FullName, type.FullName);


     SPUserCodeService userCodeService = SPUserCodeService.Local;


     userCodeService.ProxyOperationTypes.Remove(proxyOperationType);


     userCodeService.Update();


 Subscribe to my blog