Tuesday 16 July 2013

Deploy a form library via WSP

So you've created an InfoPath form, and now you want to deploy it to a library, but your SharePoint admin will light you on fire should you dare connect to production through InfoPath. So the question is; how do we deploy our InfoPath form declaratively via visual studio? Well let’s start by making a simple InfoPath form. 
With your simple form ready, make sure to set the permission on the form to domain, and  promote the properties through the advanced form option.  Once your form is configured publish it to a network location, when that’s complete open up visual studio and create a content type that inherits from the form base type. It should look something like:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!-- Parent ContentType: Form (0x010101) -->
  <ContentType ID="0x010101004663c851f85b42f59d84e3bf2359a33f"
               Name="SimpleForm_CT"
               Group="Custom Content Types"
               Description="My Content Type"
               Inherits="TRUE"
               Version="0">
    <FieldRefs>
    </FieldRefs>
  </ContentType>
</Elements>

That’s what the Declarative xml for the content type should look like, now what we are going to do is bring our published form into our content type and deploy it using a module. 

Now with your published form added select the properties and ensure that:
  • The Deployment type is set to element file
  • The Deployment path is set to the root of the content type.


Notice how the deployment type property is set to ElementFile and that the deployment location path is cleared out. If you forget to do this your form will not be visible in the Mange form templates page in central admin.


Now with your info path form brought into your content type and the properties set correctly we have to add a module to deploy the InfoPath form, you can either do this in your Content type, or add a completely separate module file. In my opinion since it’s tightly coupled with the content type, I’d keep them together, but what do I know.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!-- Parent ContentType: Form (0x010101) -->
  <ContentType ID="0x010101004663c851f85b42f59d84e3bf2359a33f"
               Name="SimpleForm_CT"
               Group="Custom Content Types"
               Description="My Content Type"
               Inherits="TRUE"
               Version="0"
               RequireClientRenderingOnNew="FALSE">
    <DocumentTemplate TargetName="/FormServerTemplates/SimpleForm.xsn"/>
    <FieldRefs>
    </FieldRefs>
  </ContentType>
  <Module Name="SimpleFormModule" Url="FormServerTemplates" RootWebOnly ="TRUE">
    <File Path="SimpleForm.xsn" Url="SimpleForm.xsn" Type="GhostableInLibrary"/>
  </Module>
</Elements>


Now you've got one more land mine to avoid, open up the feature template that you’re going to use to deploy your InfoPath form.


This is what you’ll see

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/">
</Feature>

Replace it with
<?xml version="1.0" encoding="utf-8" ?>
<Feature ReceiverClass="Microsoft.Office.InfoPath.Server.Administration.XsnFeatureReceiver"
    ReceiverAssembly="Microsoft.Office.InfoPath.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
    xmlns="http://schemas.microsoft.com/sharepoint/">
  <ActivationDependencies>
  <ActivationDependency FeatureId="C88C4FF1-DBF5-4649-AD9F-C6C426EBCBF5" />
  </ActivationDependencies>
</Feature>
If you want a more in depth explanation then just do it.

http://msdn.microsoft.com/en-us/library/microsoft.office.infopath.server.administration.xsnfeaturereceiver.aspx

Now all that’s left to do is create a list definition and instance using your content type


Then enable the management of content types through the advanced library settings.