Skip Ribbon Commands
Skip to main content

Robin | zevenseas | SharePoint Blog

:

The zevenseas Community > Blogs > Robin | zevenseas | SharePoint Blog > Posts > InfoPath attachment workflow activity
February 26
InfoPath attachment workflow activity

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 :

  • GetDocumentsFromForm
  • 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!

Comments

Cathy Wade

Thank you. This was very informative.
Robin MeureNo presence information on 16/11/2008 07:41

jake

hi robin,
how about looping through one field from you infopath form to populate a dropdown? how would you approach it?

sample in your infopath form there's a field ddlVP, then I had a webpart class with dropdown, then i need to populate that dropdown through the values from that field and i am looking from all infopath forms saved in my doclib?

i hope you could help me.
Robin MeureNo presence information on 16/11/2008 07:41

Andy

Great. Will this work with browser enabled forms?
Can you please provide  complete code for WF and .cs?
Robin MeureNo presence information on 16/11/2008 07:41

Robin

@Jake, are all the forms the same? If so please take a look at previous posting from mine http://glorix.blogspot.com/2007/11/getting-infopath-attachments-from.html

Make sure you read that and that just loop through all the infopath forms in your forms library and get all the values from the field you want.

@Andy, yes this works for browser enabled forms ;) And it's not very hard to create a custom activity. Just google on 'm and replace their 'actual' code with this code.

Robin MeureNo presence information on 16/11/2008 07:41

Andy

So from XmlTextReader reader = null; to web.Dispose(); will go inside the activity code? Sorry, our developer was fired and I only am a sys admin. Thanks much
Robin MeureNo presence information on 16/11/2008 07:41

Tina

I tired to compile it but getting below errors.
1: ListItemID doesn't exist in current context.
2:The Type or Namespace "InfoPathAttachmentDecoder" could not be found. Thank you for this awesome post.
Robin MeureNo presence information on 16/11/2008 07:41

Robin

@Tina,

to get the InfoPathAttachmentDecoder function, check out the following kb article : http://support.microsoft.com/kb/892730
Robin MeureNo presence information on 16/11/2008 07:41

System Account on 25/03/2009 16:14
 

 Statistics

 
Views: 4401
Comments: 8
Tags:
Published:1645 Days Ago