Monday, January 11, 2010

Server-side generation of InfoPath email

In a SharePoint based application, we utilize InfoPath Forms Server to serve InfoPath forms. The reason to apply InfoPath are the well-known: to enable business itself to design and maintain the forms, within a rich designer tool [the InfoPath designer]. To make that viable, a design principle is to keep the forms as slim and simple as possible. Meaning, no (complex) business logic embedded in the forms, no code behind, no web services invocation; just restrict to form input and validation. Another advantage of this restricted InfoPath usage, is that business can itself directly deploy the forms. These type of forms do not require FullTrust, nor is it needed to approve and activate them by IT operations in central admin.
A requirement is to email the forms; to a functional mailbox, and conditionally to the end-user him/herself. The latter is flagged by an option on the form. A management requirement is that the mailbox per form type must be configurable, without need to modify the forms. The only allowed management actions on the form level are for altering data collection and form display/layout.
InfoPath provides standard functionality to automatically email the form upon submit. However, because the destination functional mailbox may not be hardcoded in the form (the management requirement); and because of the conditional email copy to end-user would result in a more complex submit option; I rejected that solution approach. Instead I opt for a setup in which the form email handling is done via server side code. The high level design:
  • associate an SPItemEventReceiver for the ItemAdded event of new instances of the Form ContentType. The SPItemEventReceiver can either be associated at the ContentType definition, or per FormLibrary
  • The SPItemEventReceiver handles the emailing of each new added form. One to the configurable functional mailbox. This setting can thus be server side retrieved and applied, and it can be managed without need to modify the form for this. And if the end-user selected so in the form, then also send a copy to the end-user mailbox. This conditional logic can easily be developed within the SPItemEventReceiver handling
To set up the email-version of a submitted form, it is needed to retrieve the form data, and transform that into an email body-message. Design decision here is to apply the same view translation as embedded within the source form template. Rationale for that decision is that the email layout always will correspond with the displayed form layout. In that context, it is desired to retrieve the view stylesheet directly from the source form template self. Then the email layout will remain to automatically follow the form layout, irrespective of changes made in the form layout by business. With this, the steps to setup the email body are:
  1. read in the xmfile associated with the added form item
  2. retrieve the mso-infoPathSolution processing instruction, and parse the name of the source form template
  3. download the source form template, and extract the view stylesheet from the cabinet container
  4. cache the relation <name source form template, view> for later added forms the view can directly be found without need to get it from the source form template
  5. apply the view stylesheet to transform the data of the xmlfile into html
The result is an email message in the same layout as the form rendering within InfoPath Forms Server. Warning: typically the resulting message is too large to be correctly handled by SPUtily.SendMail, so best to apply SmptClient instead for sending the email.

No comments:

Post a Comment