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