Programmatically create InfoPath form using CSOM SharePoint 2010

The blog posts below describe how to create InfoPath form instance using server side code and the class InfopathFormGrocker
http://platinumdogs.me/2010/09/02/sharepoint-programmatically-creating-infopath-form-instance-documents-part-2-of-2/
http://platinumdogs.me/2010/07/28/sharepoint-programmatically-creating-infopath-form-instance-documents-1-of-2/

To use CSOM the application has to be modified as follows

1. Add the following assemblies
Microsoft.SharePoint.Client.dll
Microsoft.SharePoint.Runtime.dll

2. Get the InfoPath file from the content type

var clientContext = new ClientContext(siteUrl);
var list = clientContext.Web.Lists.GetByTitle(listName);

//get list level content type using ContentTypeExtensions
var listContentType = clientContext.Web.Lists.GetByTitle(listName).ContentTypes.GetByName(listContentTypeName);
var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, listContentType.DocumentTemplateUrl);

In the above example ContentTypeExtensions has been used to be able to get content type by name. More information can be found at
http://sharepoint.stackexchange.com/questions/115499/get-a-content-type-by-name-title-using-csom

3. Using InfopathFormGrocker, the manifest.xsf and template.xml need to be extracted after converting the fileInfo object into memorystream

// get the Manifest xsf file
var memoryManifest = new MemoryStream();

byte[] bufferManifest = new byte[1024 * 64];
int nreadManifest = 0;
while ((nreadManifest = fileInfo.Stream.Read(bufferManifest, 0, bufferManifest.Length)) > 0)
{
memoryManifest.Write(bufferManifest, 0, nreadManifest);
}

xsnForm.ExtractComponent(memoryManifest, "manifest.xsf");
XmlDocument formManifest = xsnForm.ComponentContent;

//memory is closed explaining why it is reinitialised
fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, listContentType.DocumentTemplateUrl);

// get the template Xml file

var memoryTemplate = new MemoryStream();

byte[] buffer = new byte[1024 * 64];
int nread = 0;
while ((nread = fileInfo.Stream.Read(buffer, 0, buffer.Length)) > 0)
{
memoryTemplate.Write(buffer, 0, nread);
}
xsnForm.ExtractComponent(memoryTemplate, "template.xml");
XmlDocument xsnFormTemplate = xsnForm.ComponentContent;

// get form metadata values
XmlNamespaceManager NamespaceManager = CreateNamespaceManager(formManifest);
string Name = formManifest.DocumentElement.GetAttribute("name", "");
string SolutionVersion = formManifest.DocumentElement.GetAttribute("solutionVersion", "");
string ProductVersion = formManifest.DocumentElement.GetAttribute("productVersion", "");

string HRef = listContentType.DocumentTemplateUrl;

XmlDocument formXML = CreateFormInstanceDocument(xsnFormTemplate.OuterXml, Name, SolutionVersion, ProductVersion, HRef);
//Manipulate the XMLDocument , e.g. update field properties
.......................................................

4. Use CSOM to upload the InfoPath to the library after converting the XmlDocument into MemoryStream


var formBytes = Encoding.UTF8.GetBytes(formXML.OuterXml);

MemoryStream xmlStream = new MemoryStream(formBytes);

clientContext.Load(list.RootFolder);
clientContext.ExecuteQuery();

var fileUrl = String.Format("{0}/{1}", list.RootFolder.ServerRelativeUrl, string.Format("Test creating InfoPath{0}.xml", DateTime.Now.ToString("yyyyMMddHHmmss")));

Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, fileUrl, xmlStream, true);

The code has been tested against SharePoint 2010. Might require some amendments to make it work for other versions of SharePoint

Advertisements

One thought on “Programmatically create InfoPath form using CSOM SharePoint 2010

  1. Pingback: CSOM SharePoint Update Created Field of InfoPath file in Document Library | reshmeeauckloo

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s