If all went right you are reading this through my new weblog that is located at : http://community.zevenseas.com/blogs/robin. Hopefully for you, the rss-reader, you won't notice the change of the transition ;)
A few posts ago I wrote about a console application which extracted attachments from a published infopath document. In that post I described that it was pretty cool that by using some fancy techniques you could access all of your infopath fields through an object model by creating XSD classes. Sure this is really good technique, it is not very generic. If you have multiple infopath documents, you will need to create a schema for each of your infopath forms. That's why I decided to discard the technique and went for a more simple solution which is generic.
XmlTextReader reader = null;
System.IO.StreamReader str = new System.IO.StreamReader(file.OpenBinaryStream());
reader = new XmlTextReader(str);
while (reader.Read())
{
if (reader.Value.Length > 255)
{
UploadIntoSharePoint(reader.Value);
}
}
So.. If the length of the value within a field is larger than 255 characters I assume that it is an attachment. I know.. it's tricky because you can have a multineline field which can hold more than 255 characters. I have to figure out what the best magical value could be to distinctively identify what could be an attachment and what not.
But it does the trick right now ;) Next thing is to embed the code in a custom workflow activity! My activity accepts the following parameters :
- Url (url of the SharePoint web)
- Form Library (name of the form library where the forms get published to)
- FormItemID (ID of the form item)
- Target Document Library (target document library to store the attachments in)
Next to do that I use two functions :
private void GetDocumentsFromForm()
{
Uri uri = new Uri(Url);
SPWeb web = new SPSite(Url).OpenWeb();
SPList formlist = web.Lists[ListName];
SPListItem formitem = formlist.GetItemById(Convert.ToInt32(ListItemID));
SPFile file = formitem.File;
XmlTextReader reader = null;
System.IO.StreamReader str = new System.IO.StreamReader(file.OpenBinaryStream());
reader = new XmlTextReader(str);
while (reader.Read())
{
if (reader.Value.Length > 255)
{
UploadIntoSharePoint(reader.Value);
}
}
}
UploadIntoSharePoint
private void UploadIntoSharePoint(string attachment)
{
Uri uri = new Uri(Url);
SPWeb web = new SPSite(Url).OpenWeb();
SPFolder AttachmentStore = web.GetFolder(DocumentLibrary);
SPList formlist = web.Lists[ListName];
SPListItem formitem = formlist.GetItemById(Convert.ToInt32(ListItemID));
try
{
InfoPathAttachmentDecoder Attachment = new InfoPathAttachmentDecoder(attachment);
SPFile newfile = AttachmentStore.Files.Add(Attachment.Filename, Attachment.DecodedAttachment);
SPListItem item = newfile.Item;
item["RelatedForm"] = formitem.ID + ";#" + formitem.Title.ToString();
//item["DocumentationType"] = type.ToString();
item.Update();
}
catch (Exception error)
{
Console.WriteLine(error.Message.ToString());
}
web.Close();
web.Dispose();
}
So that's pretty much it.. let me know what you think!