<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5487613147308590882</id><updated>2012-01-06T01:28:27.306-08:00</updated><category term='SharePoint'/><category term='workflow'/><category term='InfoPath'/><title type='text'>SharePoint Development</title><subtitle type='html'>A look into the world of application development for SharePoint</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://spappdev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5487613147308590882/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://spappdev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Michael</name><uri>http://www.blogger.com/profile/11859628414430874181</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-Xf2UyWwtbjU/TkQ7QAa6-7I/AAAAAAAAPec/m0GtyZHAFXQ/s1600/DSCN2739.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>1</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5487613147308590882.post-3457231605412550102</id><published>2009-03-24T17:24:00.000-07:00</published><updated>2009-03-26T18:38:41.780-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SharePoint'/><category scheme='http://www.blogger.com/atom/ns#' term='InfoPath'/><category scheme='http://www.blogger.com/atom/ns#' term='workflow'/><title type='text'>Programatically Extract Attachments from InfoPath Forms</title><content type='html'>&lt;strong&gt;Problem&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;You have an InfoPath form stored in a SharePoint Form Library. You want to run a workflow on this InfoPath form and let the workflow extract the file attachments and upload them to a document library.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;br /&gt;Use the &lt;strong&gt;SPFile&lt;/strong&gt; object of the &lt;strong&gt;SPListItem&lt;/strong&gt; object that the workflow is running on to access the file that represents the XML of the InfoPath form. Load the XML into an &lt;strong&gt;XmlDocument&lt;/strong&gt; object for read/write access. Get the base64-encoded value of the &lt;strong&gt;File Attachment&lt;/strong&gt; field and decode it. Extract the file name and file contents from the decoded string. Upload the results to a document library. Clear the &lt;strong&gt;File Attachment&lt;/strong&gt; field to remove the attachments from the InfoPath form. Replace the original XML of the &lt;strong&gt;SPFile&lt;/strong&gt; object with the modified XML of the &lt;strong&gt;XmlDocument&lt;/strong&gt; object.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Discussion&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This article assumes that you have created an InfoPath form template that has a &lt;strong&gt;File Attachment&lt;/strong&gt; field named &lt;strong&gt;Attachment&lt;/strong&gt;, and published the InfoPath form template to a SharePoint Form Library. I also assume you have a variable &lt;strong&gt;workflowProperties&lt;/strong&gt; bound to the workflow properties.&lt;br /&gt;&lt;br /&gt;First we retrieve the &lt;strong&gt;SPFile&lt;/strong&gt; associated with the item... this file is the InfoPath form. If the form doesn't exist, then we exit.&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;&lt;/blockquote&gt;SPFile file = workflowProperties.Item.File;&lt;br /&gt;if (file == null)&lt;br /&gt;  return;&lt;/pre&gt;Next, we get the binary stream from the form and load it into an XPathDocument&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;// Get the binary stream of the file&lt;br /&gt;Stream formStream = file.OpenBinaryStream();&lt;/pre&gt;&lt;pre&gt;// Load the stream into an XPathDocument object&lt;br /&gt;XmlDocument ipForm = null;&lt;br /&gt;ipForm.Load(formStream);&lt;/pre&gt;Create a NameSpaceManager object and add the namespace of the form to it&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;XmlNamespaceManager ns = new XmlNamespaceManager(ipForm.NameTable);&lt;br /&gt;ns.AddNamespace("my", &lt;em&gt;"&lt;strong&gt;namespace_of_form&lt;/strong&gt;");&lt;/em&gt;&lt;/pre&gt;Get the XML node containing the file attachment&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;XmlNode attachmentNode = ipForm.SelectSingleNode("/my:Attachment");&lt;/pre&gt;Decode the base64 encoded string into bytes&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;byte[] attachmentNodeBytes = Convert.FromBase64String(attachmentNode.InnerXml);&lt;/pre&gt;Position 20 contains a DWORD indicating the length of the filename buffer.&lt;br /&gt;The filename is stored as Unicode so the length is multiplied by 2&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;int fnLength = attachmentNodeBytes[20] * 2;&lt;br /&gt;byte[] fnBytes = new byte[fnLength];&lt;/pre&gt;The actual filename starts at position 24&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;for (int i = 0; i &gt; fnLength; i++)&lt;br /&gt;{&lt;br /&gt;   fnBytes[i] = attachmentNodeBytes[24 + i];&lt;br /&gt;}&lt;/pre&gt;Convert the filename bytes to a string. The string terminates with '\0' so the actual filename is the original filename minus the last character&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;char[] charFileName = UnicodeEncoding.Unicode.GetChars(fnBytes);&lt;br /&gt;string fileName = new string(charFileName);&lt;br /&gt;fileName = fileName.Substring(0, fileName.Length - 1);&lt;/pre&gt;The file is located after the header, which is 24 bytes long (plus the length of the filename)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;byte[] fileContents = new byte[attachmentNodeBytes.Length - (24 + fnLength)];&lt;br /&gt;for (int i = 0; i &lt; fileContents.Length; i++)&lt;br /&gt;{&lt;br /&gt;   fileContents[i] = attachmentNodeBytes[24 + fnLength + i];&lt;br /&gt;}&lt;/pre&gt;Open the document library&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SPDocumentLibrary docLib = (SPDocumentLibrary)workflowProperties.Web.GetList(&lt;em&gt;url_to_doc_library&lt;/em&gt;);&lt;/pre&gt;Get the root folder&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SPFolder folder = docLib.RootFolder;&lt;/pre&gt;Get the files in the folder&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SPFileCollection files = folder.Files;&lt;/pre&gt;Upload the file to the document library using the folder URL and filename we retrieved earlier&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SPFile file = files.Add(folder.Url + "/" + fileName, fileContents);&lt;/pre&gt;Get the list item of the file we uploaded and set the title to the filename&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SPListItem fileAdded = file.Item;&lt;br /&gt;fileAdded["Title"] = fileName;&lt;/pre&gt;Save the list item&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;fileAdded.Update();&lt;/pre&gt;Remove the attachment from the InfoPath form. We do this by deleting the InnerXml and then adding the attribute &lt;em&gt;xsi:nil=true&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;attachmentNode.InnerXml = string.Empty;&lt;br /&gt;XmlNode nilAttribute = ipForm.CreateAttribute("xsi", "nil", &lt;a href="http://www.w3.org/2001/XMLSchema-instance"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/a&gt;);&lt;br /&gt;nilAttribute.Value = "true";&lt;br /&gt;attachmentNode.Attributes.SetNamedItem(nilAttribute);&lt;/pre&gt;Convert the XML document to bytes&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;attachmentNodeBytes = Encoding.UTF8.GetBytes(ipForm.OuterXml);&lt;/pre&gt;Close the file stream&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;formStream.Close();&lt;/pre&gt;Save the bytes of the XML document as the contents of the SPFile object that represents the InfoPath form&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;file.SaveBinary(attachmentNodeBytes);&lt;/pre&gt;Save the changes made to the SPFile object&lt;br /&gt;&lt;pre&gt;file.Update();&lt;/pre&gt;&lt;br /&gt;That's it! Your workflow should now be able to extract the attached document and upload it to a document library.&lt;br /&gt;&lt;br /&gt;Sources:&lt;pre&gt;&lt;a href="http://www.bizsupportonline.net/infopath2007/set-infopath-form-field-value-sharepoint-workflow.htm"&gt;http://www.bizsupportonline.net/infopath2007/set-infopath-form-field-value-sharepoint-workflow.htm&lt;/a&gt;&lt;/pre&gt;&lt;pre&gt;&lt;a href="http://www.bizsupportonline.net/blog/2009/03/programmatically-rename-infopath-file-attachment/"&gt;http://www.bizsupportonline.net/blog/2009/03/programmatically-rename-infopath-file-attachment/&lt;/a&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5487613147308590882-3457231605412550102?l=spappdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spappdev.blogspot.com/feeds/3457231605412550102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://spappdev.blogspot.com/2009/03/programatically-extract-attachments.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5487613147308590882/posts/default/3457231605412550102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5487613147308590882/posts/default/3457231605412550102'/><link rel='alternate' type='text/html' href='http://spappdev.blogspot.com/2009/03/programatically-extract-attachments.html' title='Programatically Extract Attachments from InfoPath Forms'/><author><name>Michael</name><uri>http://www.blogger.com/profile/11859628414430874181</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-Xf2UyWwtbjU/TkQ7QAa6-7I/AAAAAAAAPec/m0GtyZHAFXQ/s1600/DSCN2739.JPG'/></author><thr:total>7</thr:total></entry></feed>
