Monday, March 22, 2010

Creating a SharePoint Document Library in CRM 4.0

After reading a few posts on SharePoint and CRM 4.0 integration, and learning of a new business requirement that someone came up with for the CRM deployment I am working on, I managed to get a plug-in created that will create a document library in SharePoint when a new custom entity is created in CRM 4.0.

I basically performed these steps:

1) Added a new attribute to my custom entity, in this case it was called new_projectspdocliburl of type nvarchar with a length of 200.

2) Added a new tab to the custom entity form, and added a new iframe called IFRAME_SharePoint, unchecking Restrict cross-frame scripting.

3) Added the new field to the tab (the field has to be on the tab for some JavaScript used later).

4) Saved and published the changes to the entity.

5) Create a new VB.Net Class Library project in Visual Studio 2008, calling it ProjectCreateSPDocLibPlugin, and renaming Class1.vb to plugin.vb

6) Added a web reference to SharePoint's Lists.asmx for the site you want the document library to be created in (http://servername[:port]/site_name/_vti_bin/Lists.asmx) and using a reference name of SharePoint.

7) Added a reference to System.Web.Services (found in the .Net tab of the add reference dialog) and a reference to micrsoft.crm.sdk.dll and microsoft.crm.sdktypeproxy.dll (which can be found in the sdk/bin folder of the CRM 4.0 SDK)

8) Used the following code in plugin.vb:

Imports Microsoft.Crm.Sdk
Imports Microsoft.Crm.SdkTypeProxy
Imports ProjectCreateSPDocLibPlugin.SharePoint 'This is the namespace of this project + the Reference name of the SharePoint web reference

Public Class plugin
 Implements IPlugin

 Public Sub Execute(ByVal context As Microsoft.Crm.Sdk.IPluginExecutionContext) Implements Microsoft.Crm.Sdk.IPlugin.Execute
     'Get the name of the target entity and its GUID
     Dim dynamicEntity As DynamicEntity = CType(context.InputParameters.Properties("target"), DynamicEntity)
     Dim entityName As String = dynamicEntity("new_projectname").ToString 'replace new_projectname with the name of your custom entity's primary attribute
     Dim entityId As String = context.OutputParameters.Properties("id").ToString

     'SharePoint Document Library is type 101
     Dim spDocLibListType As Integer = 101

     'Use the SharePoint's Lists.asmx to create a new list object
     Dim listService As New Lists()
     listService.Credentials = New System.Net.NetworkCredential("username", "password", "domain") 'Replace these with your own
     listService.Url = "http://servername[:port]/site_name/_vti_bin/Lists.asmx" 'Replace this with your own
     Dim listResult As System.Xml.XmlNode = listService.AddList(entityName, entityName + " Documents", spDocLibListType)
     Dim returnXML As String = listResult.InnerXml.ToString()

     'Update the Custom Entity to store the URL of the new document library
     Dim customEntity As New DynamicEntity()
     customEntity.Name = "new_customentityname" 'Replace this with your own entity name
     customEntity("new_customentityid") = New Key(New Guid(entityId)) 'Replace this with your entity's ID attribute name
     customEntity("new_projectspdocliburl") = "http://servername[:port]/site_name/" + entityName + "/Forms/AllItems.aspx"

     'Use the IPlugin interface to create a reference to the CrmService
     Dim crmService As ICrmService = context.CreateCrmService(True)
     crmService.Update(customEntity)
 End Sub
End Class
9) Compiled the project and used the Plug-in Registration tool to register the new plugin and then registered a new step with a Message of Create, the Primary Entity being the custom entity and making sure it's a Post Event step (it will be triggered after the core processing of the entity creation in the event pipeline).

10) Added the following JavaScript code to the OnLoad method of the custom entity's form:

var CRM_FORM_TYPE_CREATE = 2;
if (crmForm.FormType == CRM_FORM_TYPE_CREATE)
{
var spDocLibUrl = crmForm.all.new_spdocliburl.DataValue;
crmForm.all.IFRAME_SharePoint.url = spDocLibUrl;
}
11) Save the changes and once again publish the custom entity.

Now, all things going to plan, when you create a new object from your custom entity, once it is created, your plug-in will kick in and create a new document library in SharePoint using the name of the created object, and update the IFRAME on the form so the users can see the document library.

Obviously, the users need to already have permission to see the library in SharePoint. Another thing to consider is that the view we used, AllItems.aspx, is potentially going to show a full SharePoint page in the IFrame. It might look a bit off to have all the standard SP navigation inside the CRM frame. I don't know enough about SharePoint to explain how to work around that.

But this should have given you a good enough start into integrating SharePoint and CRM to give better document handling than the standard attachments to a CRM object.