I needed to send the completed (ie approved) form, read-only, to the company who took care of the orders made in an InfoPath 2003 form. The form is stored in a SharePoint forms library, but the receiving company didn’t have access to this SharePoint site. 2007 would be sweet, but I can’t use that. Hmmm… how to do?

I created a web service, which the form, once approved, sent an email through (all stages in the workflow before approval used the ordinary data connection to the SharePoint forms library).

The web service receives the xml document from InfoPath, via the normal web service data connection available. The web service extracts the filename (stored as a secondary data source inside the form) and makes an html document out of the xml and xsl combined, which then can be viewed on any computer with an internet browser.

There’s one big-ass downside with this though. The xsl file has to be extracted from the infopath form and then edited a little to remove not-supported functions and so on, or else you’ll se some nasty error messages when opening the form in the browser. So if the form has undergone some major changes, you need to re-extract the xsl-file and put it somewhere where the web service can access it, which in my case is in the web service root directory. 

Here’s the code:

Service.cs


[WebMethod]
  public string InfoPathMailer(XmlDocument xmlDoc)
  {
    string filename = GetFileName(xmlDoc);
Stream stream = new MemoryStream();
    XslCompiledTransform xslTransform = new XslCompiledTransform();
    xslTransform.Load(Server.MapPath("view1.xsl"));
    xslTransform.Transform(xmlDoc, null, stream);
    stream.Position = 0;
MailSender m = new MailSender("yourmailserver.net", "formsrobot@yourdomain.com", "receiver@company.com", "New End User Request", "Do not reply to this address", filename, stream);
    m.Send();
    return "";
  }
private string GetFileName(XmlDocument xmlDoc)
  {
    string infoPathNamespacePrefix = "my";
    string infoPathNamespaceURI = @"http://schemas.microsoft.com/office/infopath/2003/myXSD/2006-11-13T10:36:39";
    XmlNamespaceManager namespaceMngr = new XmlNamespaceManager(xmlDoc.NameTable);
    namespaceMngr.AddNamespace(infoPathNamespacePrefix, infoPathNamespaceURI);
    XmlNode node = xmlDoc.SelectSingleNode("//my:Filename", namespaceMngr);
    string s = node.InnerText;
    s = s.Replace("xml", "html");
    return s;
  }

And here’s the code for the class MailSender:


using System;
using System.Data;
using System.Configuration;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.IO;
public class MailSender
{
  MailMessage mail;
  String smtpServer;
  //Constructor for attachment as stream
  public MailSender(string server, string sender, string receiver, string subject, string body, string filename, Stream stream)
  {
    smtpServer = server;
    mail = new MailMessage(sender, receiver, subject, body);
    Attachment attachment = new Attachment(stream, filename, MediaTypeNames.Text.Html);
    mail.Attachments.Add(attachment);
  }
public void Send()
  {
    SmtpClient client = new SmtpClient(smtpServer);
    client.Credentials = CredentialCache.DefaultNetworkCredentials;
    client.Send(mail);
  }
}

Hopefully this can help someone out there. Good luck!

Long title, eh?

My problem was to do just the above, i.e. I had to name the filled out forms with a date and time marker. Because of that, when someone changed the contents of the form, a new one was created with the same name except for the date and time, where as I wanted it to amend the existing file but keep the original name.

I noticed on Google Groups that someone had a similar problem, but the solution wasn’t explained in detail (and since I’m a newbie on InfoPath 2003, it was a little challenge).

Anyway, here’s how I did it:

1. First I needed to do this in javascript, since the default submitting options didn’t allow this behaviour. On the Tools menu, I chose Submitting Forms and then in the Submitting Forms dialog box, clicked Enable Submit. In the Submit box, I clicked Submit Using Custom Script. Also enabled Open Microsoft Script Editor, and then I clicked OK. The Microsoft Script Editor unveiled to me for the first time, with a new function called function XDocument::OnSubmitRequest(eventObj) in place.

2. I went back to the (Design) template in InfoPath and added a textbox controller at the bottom. I named it filename, set the default value to “0″ (or whatever), and then went back to the script editor.

3. In the OnSubmitRequest function I added the following code to read the field value from the filename textbox, and if it is zero (which it will be the first time the form is used) a conditional statement that creates a new filename (plus it writes to the new/old file in the sharepoint forms library):


var blnSubmitSuccess = false;
var strPath = "http://servername/sites/sitename/projectname/formslibraryname/"; var strFilename = XDocument.DOM.selectSingleNode("//my:filename").text;if (strFilename == "0")
 {
  strFilename = ...  // Insert code here to generate a filename of your liking
  XDocument.DOM.selectSingleNode("//my:filename").text = strFilename;
 }
var strUrl = strPath + strFilename;

// Submit the form to the form library.

var objXmlHttp = new ActiveXObject("MSXML2.XMLHTTP.5.0");

try
{
  objXmlHttp.Open("PUT", strUrl, false);
  objXmlHttp.Send(XDocument.DOM.xml);
}
catch (e)
{
  XDocument.UI.Alert("Couldn't create file in SharePoint library due to the following error.\n\n"
  + e.number + " - " + e.description);
}

// Status codes of 200 or 201 indicate that the form
// has been submitted successfully.

if (objXmlHttp.Status == 200 || objXmlHttp.Status == 201)
{
  blnSubmitSuccess = true;
}

return blnSubmitSuccess;

That’s it! Now you can change the form all you like, but it will be saved properly and keep it’s original name.

Follow

Get every new post delivered to your Inbox.