Chalkboard-610

hey everyone

A couple of months to almost a year ago I had to write some documentation and lookup a lot around sandbox solutions. More precise when you would go for sandbox and when to farm solutions.

So I’ve restyled the document a little bit and you can download it as of now…

If there are some things you don’t agree or is incorrect let me know so I can change it…

Since I’m not all for re-inventing the wheel most of the information is a collection of blogs that I’ve found, all the links are saved in references at the bottom of the document.

Download:

Sandbox isn’t changed much in SharePoint 2013 so the document can be used for SharePoint 2010 and SharePoint 2013.

hope it helps someone

Today I noticed a good tool that you can use to create your own module elements files including extraction of the aspx file and automatic creation of the feature file as well.

This tool is created by Stefan stanev and can be found here.

But as I was using this I noticed that Views and Connections of connected webparts are not being extracted. So I’ve mailed Stefan and asked him if I could re-use some of his code and added some extra code so that the webpart connections are included.

The reason why I’m releasing this in a codeplex project as a webpart is because I believe that this could come in very handy for us SP developers. No longer creating the module elements file via code. Just click together what you want on a page and extract the module.

The codeplex project can be found here. Some styling still needs to be done.

First I’ve created a sandboxed solution, but this wasn’t possible because I use the SPLimitedWebPartManager . And as you can see, this is not usable in a sandboxed solution.

Ok, let’s start by explaining the module element.

In the elements file you can define multiple <Module> elements, all the possible attributes are listed below:

  1. includeFolders: (optional,string) – actually couldn’t find a single document/blog/page that describes what this attribute is for…

Karine (Bosch) found the answer:

Apparently when you have some files in your module element that need to be put in a subfolder of the library you use this attribute..

So you define includeFolders as ??-??

<Module Name=”PublishingLayoutsPreviewImages” Url=”_catalogs/masterpage” IncludeFolders=”??-??” Path=”” RootWebOnly=”TRUE”>
<File Url=”BlackVertical.png” Name=”Preview Images/BlackVertical.png” Type=”GhostableInLibrary”>
</File>
</Module>

But this didn’t actually work for me.. so use at own risk Glimlach . Don’t really think you’ll ever need this.

Also somebody noted that it add the files to all child folders.. but this I don’t believe to be the behavior.

I’ll try to find it out in code how this part behaves, will get back to this one.

  1. HyperlinkBaseUrl: (optional,string) – This specifies the absolute url to be the base url of the hyperlinks… while I have set this and deployed to other sites (different from the base url) everything still worked, so really didn’t find any real value in this attribute
  2. List: (optional, integer) – Type of list where the files included in this module should be provisioned.

Let’s go to the onet.xml file where we can find an example on this one. As you can see the master page gallery has an typeId of 116. In the module node there is a defaultmasterpage example that has list defined to 116. So the defaultmasterpage is being deployed to this library.

image_thumb2

  1. Name: (required, string) – contains the name of the file set. Nothing really special here.. just provide a name

moduleNameError

  1. Path: (optional,string) – specifies the physical path of where the files are in the features folder. By default SharePoint expects the files to be in the same folder as the feature file. But you can also define the path attribute per file node
  2. RootWebOnly: (optional, boolean) – set to false by default, if you are installing the module only in the top level web site of the site collection than you must set this to true
  3. SetupPath: (optional,string) – specifies the physical path to a folder in the 14 hivetemplate that contains a file to include in the module.

Let’s say that you want viewpage.aspx in the pages directory under the template directory than your attribute should look like

SetupPath=”pagesviewpage.aspx”

  1. Url: (optional,string) – Specifies the virtual path of the folder in which to place the files of the module. This attribute is also used to provision a folder inside a list. If the Path is not specified, the value of this attribute will be used for the physical path also.

As you can read here , we are creating a full trusted proxy with also some CAS principles.

The Full trusted proxy should be finished and now it’s time to write a Sandbox Solution that will be using this logger.

1. Make sure the Full trusted proxy is deployed at farm level and that the feature is activated.

2 Because we are calling from a partially trusted application we need to tell the DLL that this can be expected and is ok.

Go to AssemblyInfo.CS

image

And add a line at the bottom:

image

Ok now re-deploy the Trusted Proxy.

3. Create a new project under the current Visual Studio solution (Sandboxed)

3. a. Before we can use the full trusted proxy, we first need to make a reference to it’s DLL file. But first we need to add something to the Full trusted proxy.

4. Create a new code file “Logger.cs” and enter the code below, as you can see the ULSProxyArgs are being instantiated and than passed via the ExecuteRegisteredProxyOperation.

image

5. Now add a feature receiver and for this example we will create for each content type a new list + logging everything that we do.

image

image

6. Checks are being done and all the exceptions are being caught and logged. But we can also created our own exceptions and pass information to the SP logs.

7. Finally we should see something like the picture below appearing in the logs.

image

 

Now if you get into some trouble and get errors like: An operation is not legal in the current state.

Than double check the Feature receiver of the trusted proxy and what assembly and type name it passes. This is most the time the problem/solution.

Logger Code: icon_home_skydrive

The last few days I had a couple of problems with a Sandbox solution..

I created a trusted proxy to be able to log everything that happened in the sandbox solution to the SharePoint logs. Now it isn’t possible to write directly to the SharePoint logs from within the sandbox solution. Because the SharePoint logging framework relies on APIs that are not available within the sandbox.

This kind of sucks because writing code without any form of logging.. well it’s just not done..

Also, us SharePoint developers had almost all of the time the luxury to write full trusted code… Just put the assembly in the GAC and all is ok… Well with sandbox there is no GAC to speak off and this provides a somewhat different way of coding..

First of all: CAS

Here is a good list of all the execution models. Especially the sentence: “The solution runs using an isolated, low-privilege process” is the most important one.. keyword “low-privilege” ..

Also Tyler holmes blogged about it here with even the mention that we in fact expose our applications to all kinds of unnecessary security risks.

Found a “whitepaper” about Code Access Security in SharePoint 2007 for Administrators and an MSDN link for CAS in WSS 3.0 and MOSS 2007 .

Here is also the msdn link for SecurityAction enumeration .

And last but not least, the start for the entire explanation about Code Access Security .

Alright.. Now that the foundation is there let’s get started…

1. Open Visual studio and select empty SP project (name: TrustedProxyLogger) –> Farm solution

2. Add a code file (.cs) and give it “ProxyLogger” as name

3. next add 3 usings (Microsoft.SharePoint, Microsoft.SharePoint.UserCode and Microsoft.SharePoint.Administration)

4. Now you can add “: SPProxyOperation” behind the class name

image

5.What you have to do now is to override the execute method and fill in everything needed to be able to log all the information to the SharePoint Logs

image

6. Explanation of the above code part

a. check if the args are not null (if they are your code may crash and nothing appears in the SP logs

b. depends on the actions that you want to do “RunWithElevatedPrivileges” is needed. But you can leave it out here Glimlach, just wanted to show that you can do “normal” SharePoint coding here but keep in mind that you are in a full trusted assembly and at FARM level. (more on that later)

c. rest is normal stuff to be able to write trace to the SP logs.

Next up is the ULSProxyArgs class that we have to create (you’ll most likely got the red lines below the ULSProxyArgs ulsargs = args as ULSProxyArgs line..

image

7. as you can see there are 4 properties (Source, Message, Category Name and LogExpression)

a. as you can see the class must inherit SPProxyOperationArgs

b. there are constructors in place to fill the arguments so in fact you can make the properties private if you want, because they don’t need to be accessible to outside the class

c. the constructor without arguments is private because I don’t want the developer to instantiate an argument class without the basics (Category Name and a source)

image

8. in the private constructor I do some checks to see if everything is filled in or not null

image

9. we must also set the proxy args class as serializable and for our first CAS instruction we add the SharePointPermission

a. as we can see in the MSDN explanation of the Security Action enumeration

linkdemand: The immediate caller is required to have been granted the specified permission.

Since the framework of the SharePoint solutions is set to Framework 3.5 there is no need for the second part of the explanation: Do not use in Framework 4.

If SP 15 comes than this will most likely be in Framework 4 and you’ll have to change this.

b. Objectmodel = true : the explanation of MSDN is… Set this property to make a security request or demand for accessing the SP Object model…

Both of the attributes make up for the security call…

Now let’s go back to our ProxyLogger class and apply the CAS that we need..

image

10. If you set the CAS of the execute method as in the image above.. you compiler will not complain…But your code analysis will say the following:

Warning    1    CA2126 : Microsoft.Security : ‘ProxyLogger’ has one or more overridable methods with link demands that are not matched by an inheritance demand. Apply the following inheritance demands to the type: [SharePointPermission(SecurityAction.InheritanceDemand, ObjectModel = true)] 

So if we read this correctly than some CAS is already set? OK, reflector time on the SharePoint assembly (microsoft.SharePoint.dll –> Microsoft.SharePoint.UserCode namespace –> SPOperation class)

image

As we can see above the class name.. some CAS is already set in the SharePoint assemblies..

Because we’ve only used the linkdemand action the code analysis complains that there is no additional security set. And that extra security is InheritanceDemand

MSDN explanation: Add this security metadata to tell the runtime that a class must have the permission represented by the security metadata attribute to inherit from your class. So in other words.. When I call the class and I have already some security set, it will inherit that security.

So we change our code to this and all is good in code analysis wonderland…

image

As you can see, I didn’t set any CAS on the execute method.. This is because I’ve set all the security needed at Class level.. all the methods in the class will inherit this CAS setting so no need to add CAS to method level..

11. and last but not least we need to create a feature receiver so that when the feature is activated our trusted proxy will be registered for farm wide use.

12. Add a feature and set the name and description to whatever you want. But the scope must be farm level

image

13. as you can see in the code above I’m getting the assembly and full name via one of many ways. Once the new SPProxyOperationType is created than I must add it to the collection of operations and update the Usercodeservice. 

14. if the feature is being deactivated than the Proxy must be removed from the collection, it’s almost exactly the same code but with a .Remove method instead of an Add method.

15. Also the CAS line must be placed above the class name: “[SharePointPermission(SecurityAction.InheritanceDemand, ObjectModel = true), SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]”

It’s again needed for the Code access security to work correctly.

Because the length of the blog post I’ve decided to split this post in half. With this blog post you can create full trusted proxies with CAS.

In the second part of the blog post I will take the sandbox side under the loop (think it’s written this way  Glimlach ) and how to call the trusted proxy.

On a personal note: Almost nobody uses it, but in the properties of your visual studio solution, select code analysis tab.. Enable it with “Microsoft minimum recommended rules” and build you code again.

Don’t hate it (trust me, you will , especially when you are going to add stylecop as well) but learn from it. As you can see the code analysis advices you to do something but there are more ways to better coding than the advice of code analysis.

Hope it helps someone Glimlach