Appvity Blog

Home of the SharePoint mobility topics

How to Programmatically Create an InfoPath Form from an InfoPath XSN Template

By Phong Dang posted June 24, 2013 05:26 | 1 Comments

By Phong Dang posted June 24, 2013 05:26 | 1 Comments

Let's say you design an InfoPath form and upload the associated form template into the SharePoint Central Administration site. What would you do if you wanted to create a new item in the Form Library based on this template?

For example, I have a Form Library with the Project Information form and InfoPath template (Project Information.xsn) uploaded in the Central Administration site. These features are activated on the SharePoint site. I will create a new program that shows how to programmatically create an InfoPath form from an InfoPath XSN template.

First, I create a new solution and name it Appvity.InfoPathFormSoln

Next, I add two reference assemblies: Microsoft.Office.InfoPath.dll and Microsoft.Office.InfoPath.Server.dll, in order to use the InfoPath API.

 

Next, I add a new feature, Appvity.InfoPath, and set up the required information.

Note: I do not want to activate this feature automatically so I set the Active On Default option to false.

Next, I add a new event receiver for this feature. I do want to activate this feature, as my form library will update the InfoPath form and content type.

Before implementing code for this event receiver, I create a new page, FormXmlParser.aspx. This page will help me read the Project Information.xsn template and generate it to template.xml.

Note: Project Informaion.xsn is a cab file so you must extract the content before you can modify it. There are many methods to extract this file (such as: http://www.codeproject.com/Articles/15397/Cabinet-File-CAB-Compression-and-Extraction), but those methods do not work in SharePoint. Thus, I create an ASP.Net page. On this page, there is an instance of an XmlFormView control. An XmlFormView is an InfoPath Forms Services control that hosts an InfoPath form on any ASP.Net page (as long as you're running it in SharePoint). You can also host the XSN template, which is what this code will do.

Note: Note the use of the OpenFileFromPackage method in the Initialize event handler. That is a method that will extract the template.xml file (or any other file) from the XSN. The template.xml file is a "blank" form used to create a new instance of an InfoPath form from a template.

Next, to make sure this page works correctly, you want to deploy this project to a SharePoint server and browse this page:

Back to event receiver class, I implement the FeatureActivated event.

Now, you need to activate the Project Information content type in the form library and get the absolute path of the InfoPath template from the root web and then point it to your custom web page in the code and download the xml. After that, do whatever you want with the xml, and place it in a form library.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            try
            {
                string listName = "ProjectInformation";
                string strContentType = "Project Information";
                SPWeb web = properties.Feature.Parent as SPWeb;
                SPList formLibrary = null;

                try
                {
                    formLibrary = web.GetList(web.Url + "/" + listName);
                }
                catch
                {
                }

                if (formLibrary != null)
                {
                    SPContentType contentType = web.AvailableContentTypes.OfType<SPContentType>().Where(ct => ct.Name.Equals(strContentType)).FirstOrDefault();

                    if (contentType != null)
                    {
                        SPContentType infoPath = formLibrary.ContentTypes.OfType<SPContentType>().Where(c => c.Name.Equals(contentType.Name)).FirstOrDefault();

                        if (infoPath == null)
                        {
                            contentType = formLibrary.ContentTypes.Add(contentType);
                            SPFolder rootFolder = formLibrary.RootFolder;

                            //Add the content type back
                            IList<SPContentType> ctList = rootFolder.ContentTypeOrder;
                            ctList.Add(formLibrary.ContentTypes[strContentType]);
                            rootFolder.UniqueContentTypeOrder = ctList;
                            rootFolder.Update();
                            formLibrary.Update();
                        }
                        else
                        {
                            contentType = infoPath;
                        }
                    }
                    string templateUrl = contentType.DocumentTemplateUrl;
                    SPFolder forms = web.GetFolder(web.Url + "/" + listName);

                    if (forms != null)
                    {
                        WebClient client = new WebClient();
                        client.Credentials = CredentialCache.DefaultCredentials;

                        if (templateUrl.LastIndexOf("/") != -1)
                        {
                            templateUrl = templateUrl.Substring(templateUrl.LastIndexOf("/"));
                            templateUrl = "/FormServerTemplates" + templateUrl;
                        }

                        string fileInfoPath = web.Site.Url + templateUrl;
                        Stream stream = client.OpenRead(web.Url + "/_layouts/Appvity.InfoPathForm/FormXmlParser.aspx?Url=" + fileInfoPath);
                        StreamReader reader = new StreamReader(stream);
                        string formXml = reader.ReadToEnd();
                        try
                        {
                            XmlDocument xmlDoc = new XmlDocument();
                            xmlDoc.LoadXml(formXml);
                            UpdateInfoPathForm(xmlDoc);
                            Stream outStream = new MemoryStream();
                            xmlDoc.Save(outStream);
                            SPFile file = forms.Files.Add(formLibrary.Title + ".xml", outStream, true);
                            SPListItem item = formLibrary.Items[file.UniqueId];
                            item["TemplateUrl"] = fileInfoPath;
                            item.Update();
                            forms.Update();
                        }
                        catch
                        {
                        }
                    }
                }
            }
            catch
            {
            }
        }

Everything is ready. Let’s deploy the solution in our site and enjoy the results. 

 

 

 

Downloading the file demo : Appvity.InfoPathFormSoln.rar (91.82 kb).

Comments (1) -

thanks a lot for this tutorial. Can you re-upload the solution.
Thanks in advance


Log in to Appvity to comment
  • Contact Us
  • You can reach us at:
Copyright © Appvity 2015. All Rights Reserved.