-->

06/10/2012

Implementing Sandbox Proxy in Sharepoint 2010

In earlier post we have seen the Basics and Architecture of Sandbox & Sandbox Proxy.
In this post we will see how to implement one.

A sandbox is a restricted execution environment that enables programs to access only certain resources, and that keeps problems that occur in the sandbox from affecting the rest of the server environment.

Realtime applications will be hosted and executed in Sandbox environment, but its not realistic to complete a project with in scope of a Sandbox execution. There will be many situations where you need to create a file, accessing file system, execute something with Farm Admin credentials.
I have created a similar situation here. I created a Sandbox Solution with a Simple webpart, which have a simple button.
Webpart:
Code:
namespace SandboxTest.TestWebpart
{
    [ToolboxItemAttribute(false)]
    public class TestWebpart : WebPart
    {
        protected override void CreateChildControls()
        {
            Button objBtn = new Button { Text = "Submit", ID = "btnSubmit" };
            objBtn.Click += new EventHandler(btnSubmit_Click);
            this.Controls.Add(objBtn);
        }

        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            ((Button)sender).Text = FullTrustMethod( "Pratap", 100);
        }

        protected string FullTrustMethod(string strParameter, int intParameter)
        {
            string strReturnValue = "";
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                //below is a smaple operation.
                strReturnValue = strReturnValue + "String Parameter = " + strParameter + " ; Integer Parameter = " + intParameter.ToString();
            });
            return strReturnValue;
        }                                                                            
        
    }
}
The button click event will call a Fulltrustmethod(), which execute a peice of code with elivated permissions and display simple text on button, like shown below.
But if you try execute this code, you will get a error saying.
Web Part Error: Unhandled exception was thrown by the sandboxed code wrapper's Execute method in the partial trust app domain: An unexpected error has occurred.
This means, you are trying to execute full-trust code in a partail-trust environment.
This is where Proxy come into picture.There are a few steps involved in implementing and registering the proxy to execute full-trust code from a sandbox solution.

Step 1:
Create a seperate Sharepoint solution as farm solution mode. We will be moving the full trust code from sandbox solution to this farm solution. I named it as "SandboxProxyTest"

Step 2:
Create a Proxy class in which the Full-trust method will be embeded. The proxy class should be inherting SPProxyOperation base class. I named it as "ProxyFullTrustClass".

namespace SandboxProxyTest
{
    public class ProxyFullTrustClass : SPProxyOperation 
    {
        public override object Execute(SPProxyOperationArgs args)
        {
            var proxyargs = args as SandboxProxyArgs;
            return FullTrustMethod(proxyargs.strParameter, proxyargs.intParameter);
        }

        protected string FullTrustMethod(string strParameter, int intParameter)
        {
            string strReturnValue = "";
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                //below is a smaple operation.
                strReturnValue = strReturnValue + "String Parameter = " + strParameter + " ; Integer Parameter = " + intParameter.ToString();
            });
            return strReturnValue;
        }                                                                            
    }
}
Step 3:
Create a class for listing all the parameters required for the specific fulltrust method, highlighted above.
I named it as "SandboxProxyArgs.cs", which should be inheriting SPProxyOperationArgs base class.
code:
namespace SandboxProxyTest
{
    [Serializable]
    public class SandboxProxyArgs : SPProxyOperationArgs
    {
        public string strParameter { get; set; }
        public int intParameter { get; set; }
        public static string ProxyOperationTypeName
        {
            get
            {
                return "SandboxProxyTest.ProxyFullTrustMethod";
            }
        }

        public static string ProxyAssemblyName
        {
            get
            {
                return "SandboxProxyTest, Version=3.0.0.0, Culture=neutral,PublicKeyToken=104629d871066b35";
            }
        }
    }
}
Add read-only properties for the type name and assembly name of your proxy operations class. The type name should be fully qualified and the assembly name should be the four-part strong name of your assembly.

Step 3:
Make a couple of changes in AssemblyInfo.cs.
Change the version no as per the value you assign in ProxyAsseblyName proeprty.
[assembly: AssemblyVersion("3.0.0.0")]
[assembly: AssemblyFileVersion("3.0.0.0")]
Add the below attribute to make the assembly callable from sandbox solution.
[assembly: AllowPartiallyTrustedCallers]
Step 4:
Add a feature and a receiver to the fram solution. Now, we need to regsiter the proxy operation and proxy arguments with User code service, to make your proxy methods available for all sandbox callers.
We will be using the Feature activated method for this purpose.
    [Guid("36d1494b-decd-45b9-bc6e-6ad06536f81a")]
    public class SandboxProxyFeatureEventReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            //Retrieves the local user code service
            SPUserCodeService userCodeService = SPUserCodeService.Local;

            var FullTrustOperation = new SPProxyOperationType(
                            SandboxProxyArgs.ProxyAssemblyName,
                            SandboxProxyArgs.ProxyOperationTypeName);

            userCodeService.ProxyOperationTypes.Add(FullTrustOperation);
            userCodeService.Update();

        }
With this we are done with proxy creation. Deploy the project, and activate the feature which we have added. Just for verification, go to GAC and verify the assembly, its name, culture, version and public key token details are rightly mentioned in Step 3. 

Step 5:
Coming back to sandbox solution, comment the fulltrust method in webpart.cs class.
Add the refrence of the ProxySolution in this case, SandboxProxyTest.dll to sandbox project.
Now modify the btnSubmit_Click() method to call the registered proxy method instead of the Full-Trust method itself.
Code:
        protected void btnSubmit_Click(object sender, EventArgs e)
        {
           // ((Button)sender).Text = FullTrustMethod("Pratap", 100);

            var proxyargs = new SandboxProxyTest.SandboxProxyArgs();
            proxyargs.strParameter = "Pratap";
            proxyargs.intParameter = 100;

            var result = SPUtility.ExecuteRegisteredProxyOperation(SandboxProxyTest.SandboxProxyArgs.ProxyAssemblyName,
                            SandboxProxyTest.SandboxProxyArgs.ProxyOperationTypeName, proxyargs);

            ((Button)sender).Text = result.ToString();
        }
Deploy the Sandbox project and verify the web part's button execution.
Output:
Finally ! We have executed full-trust code (GAC Deployed) assembly from a sandbox project using Proxy.

Download Code Here:
SandboxproxyTest
Is it helpful for you? Kindly let me know your comments / Questions.

1 comment:

  1. thanks a lot for this cool tuturial i will try to use it on my website VPN Tunnel Installation

    ReplyDelete