Sunday, August 21, 2011

Moving CRM Attachments to SharePoint

CRM 2011 allows you to store documents in SharePoint and view them from within CRM.  Someone called Maria left me a comment asking if you could move attachments from CRM to SharePoint. My previous blogs about creating SharePoint document locations from CRM were actually prerequisites for doing exactly this.  I wanted to take a CRM attachment and move it to SharePoint. In my case it was an attachment on a letter activity as the result of a mailmerge. To be accurate it is an attachment on an annotation (or note) on a letter activity. I needed to move the attachment to SharePoint and then leave a link to the document on the letter activity. 

To achieve this we created a plugin on the PreCreate action of an annotation.  Then in the execute method of the plugin you can instantiate the annotation entity

if (null != context && null != context.InputParameters)
{
     if (context.InputParameters.Contains("Target") &&
                     context.InputParameters["Target"] is Entity)
     {
        // Obtain the target entity from the input parmameters.
        Entity entity = (Entity)context.InputParameters["Target"];
     }
}

Once you have the annotation then you can get the contents of the attachment as a byte array. 

// Retrieve the base64Encoding document body
// and convert it to byte base64encoding
// see below for the DecodeFrom64 function
byte[] documentBody = DecodeFrom64(entity.Attributes["documentbody"].ToString());
// get the filename
System.IO.FileInfo annotationFileInfo = new System.IO.FileInfo(fileName);

To remove the attachment you need to use this code
entity.Attributes["documentbody"] = null;
entity.Attributes["filename"] = null;
entity.Attributes["filesize"] = null;

The helper method for decoding the attachment to a byte array
internal static byte[] DecodeFrom64(string encodedData)
{
   byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
   return encodedDataAsBytes;
}

To upload the document to SharePoint you should use the CopyIntoItems method of the Copy web service located at http://sharepointurl/_vti_bin/Copy.asmx.  But before you do, you need to replace any illegal characters in the filename - in our case we replaced an illegal character with a hyphen.

internal static string ReplaceSpecialCharacters(string input)
{
    Regex r = new Regex("(?:[^a-z0-9 ]|(?<=['\"])s)",           RegexOptions.IgnoreCase | RegexOptions.CultureInvariant |   RegexOptions.Compiled);
    return r.Replace(input, "-");
}

I may have posted this code too late to help Maria, but I hope someone else finds it useful. 

Same blog, different theme

I've grown bored of the theme that I use for the blog and somebody posted a comment about changing the theme so I've done so.

I hope this makes the blogs easier to read.