Extracting an attachment regardless of storage mechanism

Discussions related to custom development with Select.
Post Reply
joe.mag
Posts: 122
Joined: Thu Aug 04, 2011 3:11 pm

Extracting an attachment regardless of storage mechanism

Post by joe.mag »

I'm in 4.0 (4.0.30302.1069) and have orders that predate our 2.6 to 4.0 migration. We've implemented no new archives of our own since the 4.0 migration which means we have some attachments as .fss files and some as in-database blobs.

Here's my question/issue: I'd like one way to extract the file associated with an attachment regardless of how the attachment is actually stored. As best I can tell this isn't covered anywhere (my apologies if I'm wrong). It seems like IAttachmentFile.CopyTo should be the key but it doesn't appear to offer a single interface for all attachments. I have some hacked-together code that I can post that works most of the time but, obviously, anything that doesn't work in every case is not a real solution.

Can anyone provide guidance on the "right way" to do this? Sample code would be much appreciated.
joe.mag
Posts: 122
Joined: Thu Aug 04, 2011 3:11 pm

Re: Extracting an attachment regardless of storage mechanism

Post by joe.mag »

I've stripped down my code (no real error handling, no application-specific code) and here it is:

Code: Select all

            ConnectToSoftPro();

            IOrderInfo search = os.Orders.Where(t => t.Number == "15AT018864").FirstOrDefault();

            IOrder currentOrder = os.OpenOrder(search, true);

            string strAttachmentSourcePath = "";
            foreach (IAttachmentFile attachment in currentOrder.Attachments.Items)
            {
                try
                {
                    // holding area w/ r/w privileges as desination for file fetched from stream
                    strAttachmentSourcePath = strPathToHoldingFolder + attachment.Name + attachment.Extension;

                    // prepare the writer so we can get its raw stream
                    StreamWriter wr = new StreamWriter(strAttachmentSourcePath);

                    // this seems to be the only way to get the data out of a blob
                    attachment.CopyTo(wr.BaseStream);

                    wr.Flush();
                    wr.Close();
                }
                catch (Exception exStream)
                {
                    // attempt to extract blob failed!
                    string strMessageStream = exStream.Message;
                }
            }

            DisconnectFromSoftPro();
Connect and Disconnect just handle getting attached to the SoftPro server and setting "os" to a live instance of IOrderStore.

This code works fine for 8 of 9 attachments for the example order 15AT018864. For the 9th item it fails with the exception "The given path's format is not supported." (no inner exception). Just to be sure I confirmed I can open that attachment in Select itself.
BobRichards
Posts: 1377
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Extracting an attachment regardless of storage mechanism

Post by BobRichards »

currentOrder.Attachments.Items returns IAttachmentItem objects - not IAttachmentFile objects. Is the Items enumerable passing you an IAttachmentFolder object instead of a file? You should be testing for this.
Bob Richards, Senior Software Developer, SoftPro
joe.mag
Posts: 122
Joined: Thu Aug 04, 2011 3:11 pm

Re: Extracting an attachment regardless of storage mechanism

Post by joe.mag »

Bob,

Thanks for the response. While you are exactly right and I will make that change, it actually doesn't address our specific case. The order in question has no folders in its attachments collection and yet my code fails to open 1 out of the 9 existing attachments. So your recommendation will certainly make the code more bulletproof, it won't address our problem.

I need guidance on how to get the content of the attachment for all attachments or at least help in determining if this is a bug in the API.

Thanks,

Joe
joe.mag
Posts: 122
Joined: Thu Aug 04, 2011 3:11 pm

Re: Extracting an attachment regardless of storage mechanism

Post by joe.mag »

After some more research I found the problem--some of my staff have entered document names that contain human-formatted dates (E.g. "Revised Commitment 11/03/15 12:45PM") and I gather that the API is seeing the slashes and interpreting them as parts of a path statement, not merely as the name of the attachment! I ran a test where I removed the slashes and the renamed attachment was extracted successfully.

Now the question is this: is this a bug in the API and/or could I be doing things differently to enable the extraction of other attachments named in similar ways?
BobRichards
Posts: 1377
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Extracting an attachment regardless of storage mechanism

Post by BobRichards »

I would take the position that this is not a bug since different customers may not want to alias the illegal file path characters in the same way. For example, there is no generally recognized standard conversion for a colon to something less offensive to Windows. However, thanks for pointing out the issue!
Bob Richards, Senior Software Developer, SoftPro
joe.mag
Posts: 122
Joined: Thu Aug 04, 2011 3:11 pm

Re: Extracting an attachment regardless of storage mechanism

Post by joe.mag »

I would beg to differ: there is a bug and it's this--the Select user interface is allowing people to add attachments and/or edit existing attachment names without limitation. They are allowed to enter characters that will later preclude the extraction of that attachment's content via the API. In essence the UI is not imposing a constraint that the API does which eventually cripples the API. While I agree that you can't know how a give user would choose to substitute, you can still suppress illegal characters and let the user "pretty up" the resulting stripped name as they see fit.

The fix would be to disallow characters that will break subsequent API calls or, if you prefer, make the API call impervious to illegal characters (e.g. do the needed character substitutions/suppressions on the output side rather than on the input side).

BTW we identified the following as the only disallowed keyboard characters: " < > | : * ? / \
joe.mag
Posts: 122
Joined: Thu Aug 04, 2011 3:11 pm

Re: Extracting an attachment regardless of storage mechanism

Post by joe.mag »

Since it appears we're going to have to rename our attachments to avoid breaking the API call, I am looking at programmatically stripping illegal characters from the names of existing attachments. Am I correct in thinking that I would do this as follows? BTW, this seems to work.

Code: Select all

// os is a live IOrderStore object, attachment is a live IAttachmentItem object, folder is a live IAttachmentFolder object
string strOldName = attachment.Name;

folder.DeleteItem(attachment);

string strNewName = ReplaceInvalidCharacters(strOldName);

attachment.Name = strNewName;

folder.AddItem(attachment);

 os.ApplyChanges(order);
BobRichards
Posts: 1377
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Extracting an attachment regardless of storage mechanism

Post by BobRichards »

Looks good. Glad you found a work-around.
Bob Richards, Senior Software Developer, SoftPro
Post Reply