Soon I have a task to create InfoPath form which has Attachment control, uploads file(s) to Sharepoint library and puts a link to it in the form’s body. I will describe the steps, which a used to solve the business scenario.
I choose to use Visual Studio 2008 instead of InfoPath client and created new InfoPath Form Template project.
I designed a form with following layout and data source:
Field | Type | Description |
Title | Text | Required, Text Box |
Attachment | Picture or file attachment (base64) | |
group4 | Repeating table | Two columns, Container for hyperlinks |
Url | Text | Text Box with conditional formatting (see the settings below) |
Conditional formatting for Url text box:
Select a hyperlink control from Toolbox, drag and drop it in the first column of the repeating table
and set up the properties like this
Finally, double click on “Attach File” button, open “Button Properties” dialog and select “Edit Form Code”. FormCode.cs should be open, go to Solution Explorer and add a reference to Microsoft.Sharepoint.dll
Right click on the project Add/New Item…/Code/Class and enter InfoPathAttachmentEncoder.cs for file name. Copy the source code for “Create an Encoder class in Visual Studio” from http://support.microsoft.com/kb/892730 and paste it in the new created file. Make the same for InfoPathAttachmentDecoder.cs
Use the following lines of code to upload attached file to Sharepoint document library (“Documents”), plug a hyperlink information into form content and store the form in Form library (“MyForms”)
public void btnAttach_Clicked(object sender, ClickedEventArgs e)
{
XPathNavigator attachmentNav = MainDataSource.CreateNavigator();
// Get the base64 encoded attachment
string attachedFile = attachmentNav.SelectSingleNode("//my:Attachment", NamespaceManager).Value;
attachmentNav = attachmentNav.SelectSingleNode("//my:Attachment", NamespaceManager);
// Delete the encoded file form XML form
attachmentNav.InnerXml = string.Empty;
// Get the value of "Title" field
string reference = MainDataSource.CreateNavigator().SelectSingleNode("//my:Title", NamespaceManager).Value;
// Convert the base64 encoded string into a byte array
InfoPathAttachmentDecoder decoder =
new InfoPathAttachmentDecoder(attachedFile);
byte[] attachment = decoder.DecodedAttachment;
string fileName = decoder.Filename;
// Add the file as an attachment to the SharePoint list item
using (SPSite site = SPContext.Current.Site)
{
if (site != null)
{
using (SPWeb web = site.OpenWeb())
{
// Turn on AllowUnsafeUpdates on the site
web.AllowUnsafeUpdates = true;
// Add the attached document to "Documents" library
// and set the value of "Reference" column to
// "Title" filed of the InfoPath form
SPFolder lib = web.GetFolder("Documents");
SPFile file = lib.Files.Add(fileName, attachment, true);
file.Item["Reference"] = reference;
file.Item["Title"] = fileName;
file.Item.Update();
file.Update();
// Add attachment file url to "Url" field in the form
// by adding extra "my:group4" element in the form
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(MainDataSource.CreateNavigator().OuterXml);
Uri url = new Uri(new Uri(web.Url), file.Url);
XmlNode grp4 = xdoc.SelectSingleNode("//my:group4", NamespaceManager);
XmlNode clonedNode = grp4.CloneNode(true);
clonedNode.SelectSingleNode("//my:Url", NamespaceManager).InnerText = url.AbsoluteUri;
grp4.ParentNode.InsertAfter(clonedNode, grp4);
string formXml = xdoc.OuterXml;
// Add the form to "MyForms" library
SPFolder formlib = web.GetFolder("MyForms");
string formName = string.Format("Request {0}.xml", reference);
SPFile form = formlib.Files.Add(formName, Encoding.UTF8.GetBytes(formXml), true);
form.Item["Title"] = reference;
form.Item.Update();
form.Update();
// Turn off AllowUnsafeUpdates on the site
web.AllowUnsafeUpdates = false;
// Close the connection to the site
web.Close();
}
// Close the connection to the site collection
site.Close();
}
}
}
After publishing the form and administration approval from CA site I associated the new created Content Type with existing Form library (“MyForms”).
The results:
The initial form’s XML. <my:Attachment> inner text (the encoded file) is very big and Visual Studio hides it from the preview screen
The content of <my:Attachment> here is removed
The final form’s XML, with attached file URL
The empty/new form
The final form
The uploaded documents
The forms library
Download complete Visual Studio project