How to: Deploying an Infopath form as a feature

What do we want to achieve?

It is quite easy to customize a list and create a nice form in InfoPath through InfoPath Designer, but what are the required steps to make this into a solution package so it’s available with just a few simple clicks on any site in your SharePoint farm (namely by activating a few features)? And ofcourse it should open in the browser and populate the fields!

What will we build?

  • A SharePoint 2010 solution package
    • A site collection scoped feature
      • A custom content type for the form
      • A list definition for the content type
      • A feature receiver that installs the form template and sets the render mode to browser
      • A module containing the InfoPath form (.xsn)
    • A web scoped feature
      • A list instance of the above list definition

Step 1: Design your InfoPath form

Design your InfoPath form as you normally would. Only now you store the data in fields.
When you’re satisfied with the result publish your form with the following steps:

  • Go to File > Publish and choose Publish form to a network location or file share.
  • Fill out the form template path and file name and the form template name in the first step of the wizard.
  • In the second step of the wizard clear the input and click next. You will receive a warning that users will not be able to open the form, click OK.
  • In the last step just click Publish and voila your published form is at the location you chose in step 2.

Step 2: Create a module to hold your form

  • In your visual studio project choose Add > New Item… and select Module (under SharePoint > 2010) and give it a sensible name.
  • Add your published InfoPath form from step 1.
  • Select your form and open the properties window. Then open the Deployment Location and clear the Path.
    Clear the Path
  • Now change the following things in the XML:
    <Elements xmlns=”http://schemas.microsoft.com/sharepoint/”&gt;
    <Module Name=”XSN”
    Url=”FormServerTemplates”
    RootWebOnly=”TRUE”>
    <File Path=”yourfilename.xsn” Url=”yourfilename.xsn” />
    </Module>
    </Elements>

Step 3: Create a custom content type

  • In your visual studio project choose Add > New Item… and select Content Type(under SharePoint > 2010) and give it a sensible name. Then select Form as the base content type.
  • Add the attribute RequireClientRenderingOnNew=”FALSE” to the ContentType element in the elements.xml and a Description=”YourDescriptionHere” attribute.
  • Add the following element below the FieldRefs element:

    <DocumentTemplate TargetName=”~site/FormServerTemplates/yourfilename.xsn” />
  • Add an empty elements file and define your fields. If you want these fields to automatically populate when a form is saved add the following attribute in it’s field definition:
    Node=”/my:myFields/my:myinfopathfield”

    (Also make sure you add the fieldrefs to your content type!)
  • Create a new list definition based on your content type and make sure the Type is 115 (instead of the default 10000) and add the attribute DisallowContentTypes=”FALSE”
  • Create a new list instance based on your list definition and add it to a new web scoped feature that is dependent on your site scoped feature (open the web scoped feature, scroll to the feature activation dependencies below and add your site scoped feature as a dependency.) and make sure the FeatureId attribute of the ListInstance is set to the site scoped feature ID.

Step 4: Add a feature receiver

  • Add a feature receiver to your site scoped feature containing your module from step 2 and your content type, fields and list definition from step 3.
  • Add the following dll references:
    C:\Program Files\Microsoft Office Servers\14.0\Bin\Microsoft.Office.InfoPath.Server.dll
    and
    C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.Office.DocumentManagement.dll
  • Add the following code:

    public override void FeatureInstalled(SPFeatureReceiverProperties properties)
    {
    base.FeatureInstalled(properties);

    FormsService formsService = GetFormsService();
    if (formsService == null) {
    throw new ArgumentNullException("formsService",
    string.Format("Unable to retrieve FormsService during installation of \"{0}\". Argument formsService was null.",
    properties.Feature.Definition.Name));

    }
    // Get list of form templates that are being deployed as part of this feature.
    List formTemplates = GetInfoPathFormTemplates(properties.Definition.RootDirectory);
    foreach (string formTemplate in formTemplates) {
    if (formsService.FormTemplates.ItemFromFile(formTemplate) == null) {
    FormTemplateCollection.RegisterFormTemplate(formTemplate, properties.Definition, false);
    }
    }
    }

    private static FormsService GetFormsService() {
    FormsService formsService = null;
    if (SPFarm.Local != null) {
    formsService = SPFarm.Local.Services.GetValue(string.Empty);
    } else {
    formsService = SPContext.Current.Site.WebApplication.Farm.Services.GetValue(string.Empty);
    }
    return formsService;
    }

    private static List GetInfoPathFormTemplates(string featureRootPath) {
    FileInfo[] filesInfo = new DirectoryInfo(featureRootPath).GetFiles("*.xsn");
    List infoPathFormFileSpecs = new List();
    foreach (FileInfo fileInfo in filesInfo) {
    infoPathFormFileSpecs.Add(Path.Combine(fileInfo.DirectoryName, fileInfo.Name));
    }

    return infoPathFormFileSpecs;
    }
    public override void FeatureUninstalling(SPFeatureReceiverProperties properties) {
    base.FeatureUninstalling(properties);

    FormsService formsService = GetFormsService();
    if (formsService == null) {
    throw new ArgumentNullException("formsService",
    string.Format("Unable to retrieve FormsService during uninstallation of \"{0}\". Argument formsService was null.",
    properties.Feature.Definition.Name));
    }

    // Get list of form templates that were deployed as part of this feature.
    List formTemplates = GetInfoPathFormTemplates(properties.Definition.RootDirectory);
    foreach (string formTemplate in formTemplates) {
    if (formsService.FormTemplates.ItemFromFile(formTemplate) != null) {
    formsService.FormTemplates.UnregisterFormTemplate(formTemplate, properties.Definition);
    }
    }
    }

  • Adjust the following code to match your SPContentTypeId and add it as well:

    private const string minimalActiveXToOpen = "SharePoint.OpenXmlDocuments.2";
    public override void FeatureActivated(SPFeatureReceiverProperties properties) {
    SPSite site = properties.Feature.Parent as SPSite;

    SPWeb currentWeb = site.RootWeb;

    // Update the custom content type to allow rendering in web browser.
    SPContentType formContentType = currentWeb.ContentTypes[new SPContentTypeId("0x010101003623F8B07A824955B9257C08F5AF3E8A")];
    if (formContentType.NewDocumentControl != minimalActiveXToOpen || formContentType.RequireClientRenderingOnNew) {
    formContentType.NewDocumentControl = minimalActiveXToOpen;
    // Ensure the RequireClientRenderingOnNew property is correctly set for web browsing.
    formContentType.RequireClientRenderingOnNew = false;

    // Don't forget to update the content type with the changes.
    formContentType.Update(true, false);
    }

    }

Deploy & test!

Now deploy your solution, activate your site collection feature and web feature and test that everything works as expected!

Special thanks to

  1. Stuarts Robberts – http://www.stuartroberts.net/index.php/2010/12/14/programatically-register-infopath-form-for-web-browsing-in-sharepoint/
  2. Nikkia Carter – http://www.cartermcgowanservices.com/blog/Lists/Posts/Post.aspx?ID=3

I hope this guide was helpfull to you, any feedback or comments are appreciated!

7 thoughts on “How to: Deploying an Infopath form as a feature

  1. Anonymous September 12, 2013 at 13:26 Reply

    This deploys infopath library form, not infopath list form…

    • CarolinePoint September 12, 2013 at 13:36 Reply

      Hi someone,

      Yes, that’s correct it deploys an InfoPath form library, which is a type of list.

      Caroline

  2. Andrew October 28, 2014 at 22:12 Reply

    Hi, I have followed your steps here but when I click new item on the list I get a blank form, if I go to the content type and click on edit template, the correct form shows in IP designer. If I add the Content type to another form library, then it always opens in the IP client even thought form and library are set for browser., but at least the form loaded is correct.

    Would you happen to a have a working example that i could download and compare with my test solution?

    I am attempting this on 2013 by the way.

  3. clothes March 5, 2018 at 21:32 Reply

    Amazing things here. I’m very glad to see your post.
    Thank you a lot and I’m having a look forward to contact you.
    Will you kindly drop me a e-mail?

  4. https://storify.com/akzhoan May 14, 2018 at 16:13 Reply

    I do not know if it’s just me or if everybody else experiencing problems with your site.
    It looks like some of the written text in your posts are running off
    the screen. Can someone else please comment and let me know
    if this is happening to them as well? This could be a issue with my
    internet browser because I’ve had this happen before. Cheers

Leave a comment