Walkthrough: Creating and Calling a Full-Trust Proxy Operation

This topic provides detailed steps for creating a Web Part in a sandboxed solution that uses a full-trust proxy operation to obtain contact information about the administrators of websites in the web application.

Applies to: SharePoint Foundation 2010

The first section of the topic describes how to create and deploy the full-trust proxy. The second section describes how to create and deploy the sandboxed solution that uses the proxy. For information about creating full-trust proxies from a less-specific viewpoint and for explanation of why the process requires certain steps, see How to: Create a Full-Trust Proxy Operation.

Prerequisites

Microsoft Visual Studio

Creating a Full-Trust Proxy Operation

The full-trust proxy operation that you create in this section obtains information from other websites in the farm. Specifically, it obtains the name and email address of each website administrator in a specified web application. A sandboxed solution by itself cannot obtain information outside its own site collection.

To set up the project

  1. In Microsoft Visual Studio, start an Empty SharePoint Project named WebAdminInfoOp. Make it a farm solution, not a sandboxed solution.

  2. In Solution Explorer, right-click the project name, and select Properties to open a project settings dialog box.

  3. Open the Application tab, and specify Contoso.SharePoint.UserCode as the Default namespace and Contoso.SharePoint.UserCode.WebAdminInfoOp as the Assembly name.

  4. Open the SharePoint tab, and add the following lines to the Post-deployment command line. This ensures that the Microsoft SharePoint Foundation Sandboxed Code service is restarted every time that a new version of the assembly that contains the proxy operation is deployed.

    net stop SPUsercodeV4
    net start SPUsercodeV4
    
  5. In Solution Explorer, double-click the Assembly.info file to open it, and add the following line to the end of the file.

    [assembly: AllowPartiallyTrustedCallers]
    
  6. Click the Save all files button on the toolbar.

To create the proxy operation class

  1. Add a C# class file to the project with the name GetWebsiteAdminsProxyOp.cs. Visual Studio automatically creates a class that has the same name and the namespace that you specified in an earlier step.

  2. Add the following using statements to the file.

    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Administration;
    using Microsoft.SharePoint.UserCode;
    
  3. Modify the class declaration so that the class inherits from SPProxyOperation.

  4. Add the public access keyword to the class declaration if it is not already there.

  5. Add the following demand for the SharePoint object model permission to the line above the declaration of the class.

    [Microsoft.SharePoint.Security.SharePointPermission(System.Security.Permissions.SecurityAction.LinkDemand, ObjectModel = true)]
    

    At this point, your class code should be the following.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Administration;
    using Microsoft.SharePoint.UserCode;
    
    namespace Contoso.SharePoint.UserCode
    { 
        [Microsoft.SharePoint.Security.SharePointPermission(System.Security.Permissions.SecurityAction.LinkDemand, ObjectModel = true)]
        public class GetWebsiteAdminsProxyOp : SPProxyOperation
        {
    
        }
    }
    
  6. In the body of the class, add the following override of the Execute(SPProxyOperationArgs) method. For now, ignore the errors that are generated by the reference to the WebsiteAdministratorsProxyOperationArgs class which has not been declared yet. This code ensures that your operation does nothing if the parameter that is passed to it is null and that otherwise it begins by casting the parameter to its more specific type.

    public override object Execute(SPProxyOperationArgs args) 
    {
        if (args != null) 
        { 
            WebsiteAdministratorsProxyOperationArgs myArgs = args as WebsiteAdministratorsProxyOperationArgs;
    
        }
        return null; 
    }
    
  7. Add the following lines to the body of the if condition. For now, ignore the errors that are generated by the reference to the WebAdministrators class, which has not been declared yet. Note that the reference to the SPWebApplication would not have been allowed in code that is running in a sandboxed solution.

    List<WebAdministrator> webAdmins = new List<WebAdministrator>();
    
    SPWebApplication webApp = SPWebApplication.Lookup(new Uri(myArgs.WebApplicationUrl));
    SPSiteCollection siteCols = webApp.Sites;
    
  8. The method now has to get a reference to each site collection so that it can obtain the website administrators. This requires a more privileged user account, so the code must be wrapped by a call to RunWithElevatedPrivileges. Add the following to the method below the lines that you added in the previous step.

    SPSecurity.RunWithElevatedPrivileges(delegate 
    {
    
    });
    
  9. Inside the anonymous delegate, add the following code that populates the webAdmins object that will be passed back to the calling sandboxed solution.

    foreach (SPSite siteCol in siteCols)
    {
        foreach (SPWeb website in siteCol.AllWebs)
        {
            SPUserCollection webSiteAdmins = website.SiteAdministrators;
            foreach (SPUser admin in webSiteAdmins)
            {
                WebAdministrator latestAdmin = new WebAdministrator() 
                    { Website = website.Name, Name = admin.Name, Email = admin.Email };
                webAdmins.Add(latestAdmin);
            }
        }
    }
    
  10. Immediately following the call to RunWithElevatedPrivileges, add the following line. It should be exactly before the closing bracket of the if block.

    return webAdmins;
    
  11. Below the proxy operation class, add the following declaration and implementation of a helper class that represents contact information about a website administrator. The [SerializableAttribute] is required.

    [Serializable]
    public class WebAdministrator
    {
        public String Website { get; set; }
        public String Name { get; set; }
        public String Email { get; set; }
    }
    

To create the proxy arguments class

  1. Declare a class named WebsiteAdministratorsProxyOperationArgs that inherits from SPProxyOperationArgs, and decorate it with the SerializableAttribute attribute and a demand for SharePoint object model permission.

    [Serializable] 
    [Microsoft.SharePoint.Security.SharePointPermission(System.Security.Permissions.SecurityAction.LinkDemand, ObjectModel=true)] 
    public class WebsiteAdministratorsProxyOperationArgs : SPProxyOperationArgs 
    {
    }
    
  2. This class will contain the URL of the web application that is passed from the sandboxed solution to the proxy operation. Add the following code as the body of the class.

    public WebsiteAdministratorsProxyOperationArgs(string url) 
    {
        WebApplicationUrl = url; 
    }
    
    public string WebApplicationUrl { get; set; }
    

To register the proxy operation with the sandboxed code service

  1. In Solution Explorer, right-click the Features folder, and select Add feature.

  2. Right-click the Feature1 folder, and select Rename. Rename the Feature Registration.

  3. If the Feature Designer does not open automatically, double-click the Registration feature to open it.

  4. In the designer, type Registration of Get Website Administrators Proxy Operation as the Title.

  5. Type Registers a proxy operation that sandboxed solutions can use to obtain contact information about website administrators for websites in a specified web application. as the Description.

  6. Set the scope to Farm.

  7. Save and close the designer.

  8. Right-click the Feature, and select Add Event Receiver.

  9. In the code file that is created, add the following using statements.

    using Microsoft.SharePoint.UserCode;
    using Microsoft.SharePoint.Administration;
    
  10. In the same file, override the FeatureActivated handler by using the following code.

    public override void FeatureActivated(SPFeatureReceiverProperties properties) 
    {
        Type type = typeof(GetWebsiteAdminsProxyOp);
        SPProxyOperationType proxyOperationType = new SPProxyOperationType(type.Assembly.FullName, type.FullName);
        SPUserCodeService userCodeService = SPUserCodeService.Local;
        userCodeService.ProxyOperationTypes.Add(proxyOperationType);
        userCodeService.Update();
    }
    
  11. Override the FeatureDeactivating handler by using the following code.

    public override void FeatureDeactivating(SPFeatureReceiverProperties properties) 
    {
        Type type = typeof(GetWebsiteAdminsProxyOp);
        SPProxyOperationType proxyOperationType = new SPProxyOperationType(type.Assembly.FullName, type.FullName);
        SPUserCodeService userCodeService = SPUserCodeService.Local;
        userCodeService.ProxyOperationTypes.Remove(proxyOperationType);
        userCodeService.Update();
    }
    

To deploy the proxy operation farm solution

  • On the Build menu, select Deploy.

Sandboxed Web Part That Uses the Proxy Operation

In this section are instructions for creating a sandboxed solution that you can use to test making calls to the proxy operation. The solution contains a simple Web Part that displays the returned information in a grid.

To set up the project

  1. In Visual Studio, start an Empty SharePoint Project named WebAdmInfo. Make it a sandboxed solution, not a farm solution.

  2. In Solution Explorer, right-click the References folder, and select Add reference.

  3. On the Add Reference dialog box, open the Browse tab.

  4. Browse to C:\Windows\assembly\GAC_MSIL\Contoso.SharePoint.UserCode.WebAdminInfoOp\version folder\, select Contoso.SharePoint.UserCode.WebAdminInfoOp.dll, and then click OK.

To create the Web Part

  1. In Solution Explorer, right-click the project, select Add, and then select New Item.

  2. Add a Web Part (not a Visual Web Part) named WebAdmContactInfo.

  3. In Solution Explorer, double-click the WebAdmContactInfo.webpart file to open it.

  4. Change the value of the Title property to Website Administrators Information.

  5. Save and close the file.

  6. Change the value of the Description property to Get contact information for administrators of websites in a specified web application.

  7. Right-click the Feature1 folder, and select Rename. Rename the Feature WebAdmInfoWebPart.

  8. Double-click the WebAdmInfoWebPart feature to open the Feature Designer.

  9. In the designer, type Website Administrators Contact Information Web Part as the Title.

  10. Type Displays contact information for the website administrators of websites in a specified web application. as the Description.

  11. Leave the scope set to Site.

  12. Save and close the designer.

  13. In Solution Explorer, open the WebAdmContactInfo.cs file, and add the following using statements. Note that the last of these is the namespace of the class that you derived from SPProxyOperationArgs in an earlier procedure.

    using System.Collections.Generic;
    using Microsoft.SharePoint.Utilities;
    using Contoso.SharePoint.UserCode;
    
  14. Declare the following local variables in the Web Part class.

    GridView adminGrid;
    TextBox webAppUrl;
    
  15. Replace the default override of the CreateChildControls() method with the following code.

    protected override void CreateChildControls()
    {
        Label prompt = new Label() { Text = "Enter the full URL of a web application on this farm:" };
        Controls.Add(prompt);
    
        webAppUrl = new TextBox() { Text = "https://localhost" };
        Controls.Add(webAppUrl);
    
        Button getAdmins = new Button() { Text = "Get Administrators" };
        getAdmins.Click += new EventHandler(getAdmins_Click);
        Controls.Add(getAdmins);
    
        adminGrid = new GridView();
        Controls.Add(adminGrid);
    }
    
  16. Add the following implementation of the button click event handler to the class. For now, ignore the errors from the GetAdministrators method, which has not been declared yet.

    void getAdmins_Click(object sender, EventArgs e)
    {
        adminGrid.DataSource = GetAdministrators();
        adminGrid.DataBind();
    }
    
  17. Add the following declaration of the GetAdministrators helper method.

    public List<WebAdministrator> GetAdministrators()
    {
    }
    
  18. Add the following code to set the values of the three variables that are passed to the ExecuteRegisteredProxyOperation method. Replace the placeholder with the public key token of the proxy operation assembly. To obtain the token, browse to the C:\Windows\assembly folder of the server on which the assembly is installed. Right-click the assembly, and select Properties. Copy the Public Key Token from the General tab of the Properties dialog box.

    String fourPartProxyAssemblyName = "Contoso.SharePoint.UserCode.WebAdminInfoOp, " +
                                       "Version=1.0.0.0, " +
                                       "Culture=neutral, " +
                                       "PublicKeyToken=public key token";
    
    String proxyOperationClassName = "Contoso.SharePoint.UserCode.GetWebsiteAdminsProxyOp";
    WebsiteAdministratorsProxyOperationArgs args = new WebsiteAdministratorsProxyOperationArgs(webAppUrl.Text);
    
  19. Add the following call to the ExecuteRegisteredProxyOperation method.

    Object adminsObject = SPUtility.ExecuteRegisteredProxyOperation(fourPartProxyAssemblyName,
                                                                    proxyOperationClassName,
                                                                    args);
    
  20. Add the following code to cast the returned object to its specific type and return the object.

    List<WebAdministrator> administrators = adminsObject as List<WebAdministrator>;
    
    return administrators;
    

To deploy and use the Web Part

  1. On the Build menu, select Deploy.

  2. Add the WebAdmContactInfo Web Part to any Web Parts page of the site collection to which the sandboxed solution is deployed.

  3. Enter the full URL of any web application on the farm in the text box of the Web Part (or leave it at the default "https://localhost"), and then press the Get Administrators button. A grid appears with an alphabetical listing of websites in the web application, together with the name and email address of the administrators of each website.

See Also

Tasks

How to: Create a Full-Trust Proxy Operation

Concepts

Sandboxed Solutions in Partnership with Full-Trust Proxies in SharePoint 2010

Other Resources

Sandboxed Solutions in SharePoint 2010

Sandboxed Solutions Resource Center | SharePoint 2010

SharePoint Developer Team Blog

SharePoint Developer Center