How to display InfoPath forms inline with Outlook email message

I was helping one of the customers on a proof of concept (POC) for an InfoPath based Office Business Application (OBA) and came across a feature request to display InfoPath from inline with the email message in Outlook. Providing a consistent user experience is the reason cited for that feature. I did buy into the idea as it saves a few additional clicks to display the form before filling information like expenses, order requests, etc.

I thought I am sure people on the Internet would have done that and the solution was only a few searches away :(

No matter what I did the InfoPath form always used to come as an attachment and the user was required to open it in an InfoPath instance outside Outlook. I had to make a few phone calls to Redmond and verify through Office guys to figure out a solution and I thought this will be very helpful to share it with the community.

The solution was very simple I was missing a few vital MIME types:(

Here is a sample code (not fit for production) that uses SMTP service to generate an email on the server...

  [ServiceContract]

  public interface IFormMailer

  {

  [OperationContract]

  bool MailInfoPathForm(string from, string to, string smtpServer,

  string templateName, string formName );

  }

 

When an email is generated one needs to assume that the template (.XSN) will not be on the client machine and hence both .XSN and .XML files will need to be attached. While inserting the files into the mail message, it is necessary to attach appropriate MIME types. In addition to the MIME types, necessary message headers will have to be added to make sure that Outlook treats the attachments with due processing.

Following is a simple table that lists the headers and MIME types:

InfoPath File Type

MIME Type

XSN

application/x-microsoft-InfoPathFormTemplate

XML

application/x-microsoft-InfoPathForm

 

Mail Message Header

Header Value

Content-Class

InfoPathForm.InfoPath

Message-Class

IPM.InfoPathForm.InfoPath

 

Above simple WCF contract is implemented in a skeletal FormMailer class shown below:

 

    public class FormMailer : IFormMailer

    {

     public bool MailInfoPathForm(string from, string to, string

                   smtpServer, string templateName, string formName)

      {

      try

      {

          string rootPath = @"D:\Working\InfoPathMailer\";

          SmtpClient client = new SmtpClient(smtpServer);

      // Make sure that your .NET thread is running under

    // appropriate credentials to connect to the SMTP service

          client.Credentials = CredentialCache.DefaultNetworkCredentials;

          // Specify the e-mail sender.

          MailAddress sender = new MailAddress(from);

          // Set destinations for the e-mail message.

          MailAddress receiver = new MailAddress(to);

          // Specify the message content.

          MailMessage message = new MailMessage(sender, receiver);

          message.Subject = "InfoPath test from a web service";

      // The following two lines are very important to render the

    // the InfoPath form inline with the Outlook message

          Attachment template = new Attachment(rootPath + templateName, new

               ContentType("application/x-microsoft-InfoPathFormTemplate"));

          Attachment form = new Attachment(rootPath + formName, new

               ContentType("application/x-microsoft-InfoPathForm"));

          message.Attachments.Add(form);

          message.Attachments.Add(template);

          message.Headers.Add("Content-Class", "InfoPathForm.InfoPath");

          message.Headers.Add("Message-Class", "IPM.InfoPathForm.InfoPath");

         

    // wire up an event handler for post processing

          client.SendCompleted += new

SendCompletedEventHandler(SendCompletedCallback);

          client.Send(message);

          return true;

        }

        catch (Exception e)

  {

           //do some logging for root cause analysis

           return false;

        }

      }

      private void SendCompletedCallback(object sender,

                                                   AsyncCompletedEventArgs e)

      {

      //do some logging and post processing here

      }

 

While the above solution displays the form inline with the email message, it still doesn't display it in the preview mode. I will make another post once I figure that one out.

Hope this is helpful!

Cheers,

HanuK