Fixed the Feature-based deployment of InfoPath forms to SharePoint site while treating them as first-class source artifacts in VS + TFS environment
I’m a supporter of applying Application Lifecycle Management (ALM) principles within application development projects. This also goes for SharePoint-based custom applications. Basically this means:
- designing and developing the SharePoint artifacts within a team-based source repository environment (aka, Team Foundation Server);
- applying version control to the individual application/building blocks;
- daily build;
- and full automatic and repeatable deployments
With InfoPath development, this gives some challenges. First of all, the InfoPath forms are setup and maintained via its own designer-tool, namely the InfoPath Designer client; and not directly from within the scope of Visual Studio. However, the most significant issue is the manner of deployment: the InfoPath client contains functionality to publish the InfoPath form to the destination environment, with SharePoint site as one of the available options. Given my ALM aspirations, I want to copy this InfoPath client deployment-experience to within the regular SharePoint deployments, via the
Solution framework and SharePoint
Features. In essence, I want to achieve the following:
- Automatically provision the required Information Architecture artifacts:
- SiteColumns
- Masterdata for LookupFields
- ContentTypes
- Forms Libraries, associated with the ContentTypes, for administration of the filled in InfoPath forms
- Automatically provision and activate the required InfoPath infrastructure
- InfoPath forms
- DataConnections
The first category, the Information Architecture artifacts, is well-known SharePoint provisioning. It can be done via a Site Definition, Features, or a combination. I favor the Feature-based approach, because it is modular, and allows me to turn it off and on.
The second category gave me more challenges. On internet search, I came across some posts that mentioned the SharePoint OOTB XSNFeatureReceiver that aids in here. However, it quickly appeared to me that it only takes care of one part, namely registrating the InfoPath form templates within the target SharePoint site. To successfully achieve this, XSNFeatureReceiver has constraints on the deployable InfoPath forms. And when even a single one of them does not comply to these constraints, XSNFeatureReceiver rather silently fails to correctly install the forms. Another missing part is for the DataConnections. The upload is not the issue here, being standard SharePoint Module functionality. But rather adjusting them to the specific target environment. In my ALM principles, I want to hold on to 1 single instance per DataConnection file, and not be forced to maintain versions for each of them per target environment (development, test, staging, production).
Luckily, Microsoft has not made
XSNReceiverFeature sealed. So I decided to overload it to augment the standard deployment functionality with the above described aspects. Adjusting the
DataConnections appeared rather simple, with thanks to this blog (
Building InfoPath Form Services Solutions using Visual Studio 2008), including a link to
demo provision code. I took this as basis to realize a generic approach, feeded by an XML configuration file delivered within the feature scope
The correct deployment of the InfoPath forms appeared to be more of a challenge. Eventually, I found out that the direct cause of the failed deployment was that I earlier on published the forms during my development and testing of the forms. As soon as you publish an InfoPath form, the InfoPath client administrates this within the form itself. And this appeared to result in the malfunctioning XSNFeatureReceiver based InfoPath forms registration. This can be mitiligated by correcting the InfoPath forms. An alternative is to modify the original InfoPath form artifacts. However, this would then be a corrective action to be repeated every time you’d published an InfoPath form just for an InfoPath designer (programmer) test. I therefore went for the alternative to do the correction as part of the Feature installation procedure. This way during the development phase the team can just go one and (re)publish the forms, without worrying about the effect on deployment later on.
Another thing to take into account when doing Feature-based deployment of InfoPath forms, is that the Forms must be contained at the Feature root-directory. I like to structure Feature contents within subfolders for different deployable types. ContentTypes, SiteColumns, DataConnections, and also InfoPath forms, each within their own subfolders within the feature. However, in case of InfoPath forms deployed via XSNFeatureReceiver, this is not working. Without a concrete error message, the registrating will then just not be performed. So keep your Forms at the Feature root-level.
Deployment steps, and thus functionality of InfoPathInfrastructure feature
Upon Feature installation event:
- Fix the forms files, for successful automatic publishing via XSNFeatureReceiver
- Extract the forms; this on itself presented a challenge, since .NET does not provide standard cabinet (.cab) handling
- Inspect the manifest.xsf file on the presence of publishUrl and trustLevel; remove any of them present
- Repack the .xsn container / file
Within the Feature Activation:
- upload forms files to FormsServerTemplate library
- Registrate the forms
- upload data connections to DataConnections library
- provision site columns
- provision master data lists
- fix the lookup references
- provision content types; including reference to the uploaded forms
- provision contents/data libraries
- assign content types to the contents libraries
- fix retrieve data connections --> associate with the master data list in the deploy environment (iso your local / development source)
- fix submit data connection --> associate with the content data list in the deploy environment (iso your local / development source)