How to Add the Attachment from an InfoPath 2007 Form to a SharePoint 2007 (MOSS/WSS) Document Library
I have an InfoPath 2007 Form where I have a Text Box, a File Attachment field and a Button. I changed the property of the button to make it a Submit button. My target is to post the Form’s instance into a Form Library. And then put the file which I have attached through the File Attachment field to a separate Document Library.
In the Button Properties Pop-up, I have selected “Rules and Custom Code” as Action. Added a Rule to post the Form Instance in a SharePoint Form Library. I have used VSTA to add the necessary code to the Form Template. You can find it in Tools>Programming Menu. You can use VSTO also. I added a reference of “Windows SharePoint Services” and used the following code:
using Microsoft.Office.InfoPath;
using System;
using System.Xml;
using System.Xml.XPath;
using Microsoft.SharePoint;
using System.IO;
namespace Template1
{
public partial class FormCode
{
public void InternalStartup()
{
((ButtonEvent)EventManager.ControlEvents["Submit"]).Clicked += new ClickedEventHandler(Submit_Clicked);
}
public void Submit_Clicked(object sender, ClickedEventArgs e)
{
XPathNavigator docXN = this.CreateNavigator();
XPathNavigator opnXN = docXN.SelectSingleNode("/my:myFields/my:fileup", this.NamespaceManager);
byte[] attachmentNodeBytes = Convert.FromBase64String(opnXN.ToString());
// Position 20 contains a DWORD indicating the length of the
// filename buffer. The filename is stored as Unicode so the
// length is multiplied by 2.
int fnLength = attachmentNodeBytes[20] * 2;
byte[] fnBytes = new byte[fnLength];
// The actual filename starts at position 24 . . .
for (int i = 0; i < fnBytes.Length; i++)
{
fnBytes[i] = attachmentNodeBytes[24 + i];
}
// Convert the filename bytes to a string. The string
// terminates with \0 so the actual filename is the
// original filename minus the last character !
char[] charFileName = System.Text.UnicodeEncoding.Unicode.GetChars(fnBytes);
string fileName = new string(charFileName);
fileName = fileName.Substring(0, fileName.Length - 1);
// The file is located after the header, which is 24 bytes long
// plus the length of the filename.
byte[] fileContents = new byte[attachmentNodeBytes.Length - (24 + fnLength)];
for (int i = 0; i < fileContents.Length; ++i)
{
fileContents[i] = attachmentNodeBytes[24 + fnLength + i];
}
string SiteURL = "https://myserver/sites/newsite/newdoclib/" + fileName;
SPWeb site = new SPSite(SiteURL).OpenWeb();
site.Files.Add(SiteURL, fileContents);
}
}
}
Remember, if you use coding with your InfoPath Form, you need to make it Full Trust, have to Sign it Digitally and while publishing it in a SharePoint Site it should be approved by an Administrator.