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.

1 comment:

Jason said...

Great, thank you!
I'm using this method to prevent the saving of email attachment.