In The Mix

As a SharePoint architect I have the business behind me and the Developers and IT Pro on my shoulders.

Serialization inside SandBox Solutions June 29, 2010

Filed under: SharePoint 2010 — fmuntean @ 4:27 pm
Tags:

When creating a Web Part in SharePoint 2010 that will store configuration/data inside the SP Hierarchical Store at the SPWeb  level, using automatic serialization of an object, I got into the following error: System.Runtime.Serialization.SerializationException was unhandled Message=Unable to find assembly ‘MFD.SandBoxWebPart, Version=1.0.0.0, Culture=neutral ….’

Now to explain in more details the problem and how I choose to resolve it.

The configuration class is nothing else than a DTO class containing the configuration items as public properties and the [Serializable] attribute and be as simple as this example:

  1. [Serializable]
  2. public class MyConfig
  3. {
  4.     public string Config1 { get; set; }
  5.     public long Config2 { get; set; }
  6. }

I got the previous error when adding an instance of this class into the SPWeb Properties as in the following example (the exception gets thrown at line 5):

  1. SPWeb web = SPContext.Current.Web;
  2. {
  3.     var config = new MyConfig()
  4.                     {Config1=“Value1”,Config2=123};
  5.     web.AddProperty(“Key”,config);
  6. }

Now there is nothing wrong with accessing the SPWeb properties inside the Sandbox solutions as the following code will work just fine:

web.AddProperty(“Key”,”Value”);

The problem is that the serialization mechanism inside .NET requires to load the assembly for reflection. The SandBox assembly can’t be found because it is not saved in the GAC or any of the SharePoint folders as it only resides in memory and on the Content Database.

A work around for this to create your own serialization to xml/string using custom methods that will save/restore your data using one of the .NET classes (that can be serialized because they live in GAC).

An example of new MyConfig class will look like this:

  1. [Serializable]
  2. public class MyConfig
  3. {
  4.     public string Config1 { get; set; }
  5.     public long Config2 { get; set; }
  6.     public static MyConfig FromXML(string xml)
  7.     {
  8.         XElement doc = XElement.Parse(xml);
  9.         return new MyConfig()
  10.         {
  11.             Config1= doc.Element(“Config1”).Value,
  12.             Config2 = long.Parse(doc.Element(“Config2”).Value)
  13.         };
  14.     }
  15.      public string ToXml()
  16.         {
  17.             XElement xml = new XElement(“MyConfig”,
  18.                 new XElement(“Config1”,this.Config1),
  19.                 new XElement(“Config2”,this.Config2));
  20.             return xml.ToString();
  21.         }
  22. }

Now all you have to do to store the config in SPWeb properties is to:

  1. SPWeb web = SPContext.Current.Web;
  2. {
  3.     var config = new MyConfig()
  4.                     {Config1=“Value1”,Config2=123};
  5.     web.AddProperty(“Key”,config.ToXML());
  6. }
Advertisements
 

Sandbox Solutions issue in SharePoint 2010 Beta February 2, 2010

Filed under: SharePoint 2010 — fmuntean @ 10:23 am
Tags:

For those who start building sandboxed solutions in SharePoint 2010 beta and have trouble seeing their sandboxed solution web part on the page,or deployment errors there is a known bug in there that can be corrected by applying the following Power Shell script witch fix the ACL for the sandboxed code:

 

#Fix SharePoint Sandboxed Solutions Bug – Web Part Not Visible
$acl = Get-Acl HKLM:\System\CurrentControlSet\Control\ComputerName
$person = [System.Security.Principal.NTAccount]"Users"
$access = [System.Security.AccessControl.RegistryRights]::FullControl
$inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$propagation = [System.Security.AccessControl.PropagationFlags]::None
$type = [System.Security.AccessControl.AccessControlType]::Allow
$rule = New-Object System.Security.AccessControl.RegistryAccessRule($person, $access, $inheritance, $propagation, $type)
$acl.AddAccessRule($rule)
Set-Acl HKLM:\System\CurrentControlSet\Control\ComputerName $acl