Pages

Friday 2 March 2012

Full trust proxy in SharePoint sandbox solution


You know that sandbox solution in SharePoint 2010 has certain limitation like
·         It doesn’t allow using web services.
·         You can’t access SharePoint web controls
·         It won’t allow executing code that runs under elevated privileges etc…
So, basically sandbox solution provides restricted environment to execute your code for specific SharePoint site.

What if you want to execute a web service inside a sandbox solution? The solution is to write a full trust proxy. Let’s solidify this requirement by creating a web part that gets the data from a web part. I’m going to write a simple sandbox solution that displays xml string returned from Lists.GetList(“your list name”) method.

There are three parts of this code.
·         Create a proxy: This will execute your sharepoint web service and return xml
·         Register full trust proxy.
·         Write a web part

Create a proxy
1.      Add a class library project to your solution say “RVProxy”.
2.      Add a class file inside it say “ServiceHelper.cs”.
3.      Copy and paste below code to your ServiceHelper.cs file

       
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.UserCode;
using System.Xml;

[assembly: System.Security.AllowPartiallyTrustedCallersAttribute()]
namespace RVProxy
{
    public class ServiceHelper:SPProxyOperation
    {
        public override object Execute(SPProxyOperationArgs args)
        {
            if (args != null)
            {
                ListArgs lstArg = args as ListArgs;
                string listName = lstArg.ListName;
                RVListOperation.Lists lst = new RVListOperation.Lists();
                lst.PreAuthenticate = true;
                lst.Credentials = System.Net.CredentialCache.DefaultCredentials;
                XmlNode node = lst.GetList(listName);
                return node.InnerXml;
            }
            else
            {
                return null;
            }
        }
    }

    [Serializable]
    public class ListArgs:SPProxyOperationArgs
    {
        public ListArgs(string listName)
        {
            this.ListName = listName;
        }
        public string ListName
        {
            get;
            set;
        }

    }
}

In the above code, note that assembly has been tagged with attribute [assembly: System.Security.AllowPartiallyTrustedCallersAttribute()]. This tells the compiler to execute the assembly in partially trusted environment.

Class ServiceHelper inherits SPProxyOperation class. Implement its Execute() method. This method contains all the code that runs under trusted mode.

Class ListArgs serves as an input argument sent to the proxy. Don’t forget to decorate this class with attribute  [Serializable]


Now your proxy is ready. You need to register this as full trust proxy.
Register full trust proxy
1.      Put the “RVProxy” dll into the GAC.
2.      Register this dll as full trust proxy. You can either register this using powershell script or using SharePoint object model. I’ll explain the second one here
a.       Create a windows application
b.      Use below code to register, unregister or view registered assemblies:
Register
       
private void RegisterFullTrustProxty(string assemblyName, string typeName)
        {
            label1.Text = "";
            lblRegisteredProxy.Text = "";
            SPUserCodeService service = SPUserCodeService.Local;
            if (service != null)
            {
                SPProxyOperationType getEventLogItemCreationOperation = new SPProxyOperationType(assemblyName, typeName);
                service.ProxyOperationTypes.Add(getEventLogItemCreationOperation);
                service.Update();
                label1.Text = "Updated successfully!";
            }
            else
            {
                label1.Text = "Update failed!";
            }
        }
For e.g RegisterFullTrustProxty("RVProxy, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0d35956c4346f2f1"
, "RVProxy.ServiceHelper"
);

Unregister
private void UnregisterFullTrustProxty(string assemblyName, string typeName)
        {
            label1.Text = "";
            lblRegisteredProxy.Text = "";
            SPUserCodeService service = SPUserCodeService.Local;
            if (service != null)
            {
                SPProxyOperationType getEventLogItemCreationOperation = new SPProxyOperationType(assemblyName, typeName);
                service.ProxyOperationTypes.Remove(getEventLogItemCreationOperation);
                service.Update();
                label1.Text = "Removed succesfully!";
            }
            else
            {
                label1.Text = "Remove failed!";
            }
        }

View all registered assemblies
private void ViewAllRegisteredProxy()
        {
            label1.Text = "";
            lblRegisteredProxy.Text = "";
            SPUserCodeService service = SPUserCodeService.Local;
            if (service != null)
            {
                int count = service.ProxyOperationTypes.Count;
                lblRegisteredProxy.Text = "Proxy count: " + count.ToString() + Environment.NewLine ;
                foreach (SPProxyOperationType item in service.ProxyOperationTypes)
                {
                    lblRegisteredProxy.Text += "AssemblyName: " + item.AssemblyName + Environment.NewLine + "TypeName: " + item.TypeName + Environment.NewLine;
                }
            }
        }

Write the web part
You have created the proxy as well as registered as a full trust proxy. Now it’s time to utilize this proxy in your web part code. I’m pasting here a sample code that utilizes the above proxy:


       
[ToolboxItemAttribute(false)]
    public class DemoPart : WebPart
    {
        Label lbl = new Label();
        Button btnTest = new Button()
        {
            Text = "Get List"
        };
        public DemoPart()
        {
            btnTest.Click += new EventHandler(btnTest_Click);
        }

        void btnTest_Click(object sender, EventArgs e)
        {
            string assemblyName = "RVProxy, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0d35956c4346f2f1";
            string typeName = "RVProxy.ServiceHelper";
            string listInfo = SPUtility.ExecuteRegisteredProxyOperation(assemblyName, typeName, new  ListArgs("Tasks")).ToString();
            lbl.Text += listInfo;
        }
        protected override void CreateChildControls()
        {
         
            lbl.Text = "Hi Ranvijay, here is your web part under sandbox solution.<br /><br />";
         
            Controls.Add(lbl);
            Controls.Add(btnTest);
        }

Note: The proxy runs under SPUserCodeService.exe service. So, every time you make changes to your proxy and redeploy the dll to GAC, you will need to restart the “SPUserCodeV4”. To stop use "net stop SPUserCodeV4" and to start use "net start SPUserCodeV4"


SharePoint chart using excel services


Sometimes there is a need to display chart embedded in excel sheet. SharePoint provides REST API for this. Here are the steps to display excel chart.

       

1.      Upload your excel file into the document library say “Shared Documents”.
2.      Add a content editor web part to the page where you want to display the chart.
3.      Now edit the HTML source of content editor web part and put below content

<img src="/_vti_bin/ExcelRest.aspx/Shared Documents/Book1.xlsx/Model/Charts('Chart 1')" alt=""/>​

Note: please verify the service by typing the url in browser something like
http://<your server>/_vti_bin/ExcelRest.aspx/Shared Documents/Book1.xlsx/Model/Charts('Chart 1')

“Chart 1” is the name of chart. You can set the name of the chart as follows:
a.       Open excel sheet.
b.      Click on the chart.
c.       Go to Layout menu. You will see the Chart Name box at the top right ribbon.

4.      Save the content editor web part. This should render your chart. For details about the REST API please follow Sample URL For Excel Services REST API

Why SharePoint site's first load is very slow

The sharepoint site is very slow when we access it first time. After that the response time is good. The reason is compilation and caching which takes time after application pool is recycle. To handle this we need to warm up the server whenever recycle happens. Here is a good link that explains about server warm up: http://blogs.msdn.com/b/joelo/archive/2006/08/13/697044.aspx 


So the idea is to schedule a job that pings the server whenever reset occurs.

Popular Posts